Developer guide: GitOps Airflow runner pack¶
The GitOps Airflow runner pack is a control-plane slice on top of
gitops.bundle. It helps Airflow KubernetesExecutor,
KubernetesPodOperator, and KubernetesPodExecutor-style wrappers run a custom
dpone image without teaching scheduler code about manifests, sparse paths,
bundle attestation, or runtime connector internals.
Do not import Airflow, Kubernetes clients, source/sink connectors, or database
SDKs into this slice. Generated airflow_task.py may contain Airflow imports
and generated airflow_dag_factory.py may contain KubernetesPodOperator
and PythonOperator imports because they are output artifacts, not dpone
runtime code. The generated DAG factory is an artifact-loading helper:
build_dpone_gitops_task_from_artifacts consumes kpo-kwargs.json and
pod-spec.yaml. The direct KPO mode is not the sparse git-sync runtime contract.
When a DAG repository has dpone installed in the scheduler image, use
dpone.airflow.runtime_adapter for the same reusable helper surface:
load_dpone_kpo_kwargs, build_dpone_gitops_task_from_artifacts, and
validate_dpone_artifacts; import build_dpone_gitops_step_tasks_from_artifacts
from dpone.airflow.step_tasks.
The module is intentionally DAG-side only and must not discover manifests,
compute sparse paths, choose git-sync auth, or rebuild Kubernetes PodSpecs.
Step-task rendering reads only run-spec.json; source-refresh dependencies are
already compiled there by GitOpsAirflowRunSpecBuilder.
artifact-index.json and dpone gitops airflow preflight are the release
gate around that artifact directory: index owns inventory/digests, preflight
owns schema validation, detection for stale artifacts, pod-doctor composition, and
runtime-only Airflow connection bridge plan checks, and user-facing
next_actions.
The only command that executes manifests is
dpone gitops airflow run-spec-exec; keep it behind the CommandRunner
interface so tests and docs can exercise runtime evidence without launching
real connectors. Cluster smoke execution is separate, opt-in, and isolated
behind AirflowK8sSmokeRunner. Pod launch evidence collection is also
separate, opt-in, and isolated behind AirflowPodLaunchEvidenceRunner.
Cluster readiness checks are separate from both smoke execution and pod-watch:
dpone gitops airflow cluster-doctor validates namespace, service account,
RBAC, Secret keys, ExternalSecret readiness, and quota/LimitRange visibility
without launching a pod or reading secret values.
Taxonomy¶
GitOpsAirflowArtifactRendererrenderspod_template.yaml,executor_config.json,airflow_task.py,entrypoint.sh, and delegates the artifact-loadingairflow_dag_factory.pyto the focused factory renderer from an already-produced bundle or runtime profile.dpone.airflow.runtime_adapteris the optional importable DAG-side adapter for Airflow scheduler images that already install dpone. It exposesload_dpone_kpo_kwargs,build_dpone_gitops_task_from_artifacts, andvalidate_dpone_artifacts; it only consumeskpo-kwargs.json,pod-spec.yaml, andpod-contract.json.GitOpsAirflowDoctorvalidates bundle JSON, bundle attestation presence,pod_template_fileshape,basecontainer requirements, image presence, and image contract content.GitOpsAirflowRunnerPolicyEvaluatorappliesadvisory,pr, andreleaserunner policy profiles over already-loaded bundle, pod template, and image contract payloads.GitOpsAirflowRunSpecBuilderturns an existinggitops.bundleinto orderedbundle_verify,gitops_verify, optionalsource_refresh, anddpone_runruntime steps without executing commands. It reads manifest hook metadata only to render Airflow-visible hook steps requested byexecution.airflow: separate_task.GitOpsAirflowRuntimeEvidenceVerifiervalidatesruntime-evidence.jsonagainst a run-spec without executing commands.GitOpsAirflowRuntimeProfileBuilderturns an existing bundle/run-spec pair plus runtime placement input into a stableruntime-profile.jsoncontract.GitOpsAirflowRuntimeProfilePolicyevaluatesadvisory,pr, andreleaseprofile checks over runtime placement. Release mode requires image digest, non-default service account, CPU and memory requests and limits, and an explicit ArtifactSink path.GitOpsAirflowGitSyncContract,GitOpsAirflowGitSyncAuth, andGitOpsAirflowGitSyncSparsePathare DTOs for the optional sparse git-sync runtime contract. They serialize repository ref, git-sync image, safe auth references, worktree paths, sparse checkout file, and deterministic sparse allowlist entries without secret values or local absolute paths.GitOpsAirflowGitSyncArtifactCollectoraggregates sparse checkout entries from already-rendered bundle entries andgitops.plan.sparse_paths. It does not inspect manifest schema and does not rerun manifest discovery.GitOpsAirflowRuntimeProfileGitSyncBuildermaps CLI/runtime-profile options into aGitOpsAirflowGitSyncContractand owns auth-mode blockers before the runtime profile is written. It depends on theGitOpsAirflowGitSyncPathCollectorprotocol, not on a concrete artifact reader.GitOpsAirflowConnectionBridgeBuilderdiscoversconnection_type: airflowrefs from generated bundle/plan manifest paths and builds the runtime-onlyconnection_bridgecontract. It reads raw YAML throughYamlCodec; it does not compile manifests, import Airflow, or serialize connection URI values. The public runtime-profile flags are--airflow-connection-bridge,--airflow-connection-secret, and--airflow-runtime-mode. The bridge emitsAIRFLOW_CONN_env var references only; secret values stay in Kubernetes Secrets or scheduler-provided env.GitOpsAirflowConnectionBridgePlanBuilderconsumes the already-renderedconnection_bridgecontract and buildsconnection-bridge-plan.json,airflow-connections-secret.yaml,airflow-connections-externalsecret.yaml, andairflow-connections.env.exampleskeletons. It never reads manifests, imports Airflow, calls Kubernetes, or serializes URI values.GitOpsAirflowConnectionBridgePlanServiceowns repo-relative path validation, loadsruntime-profile.jsonandpod-contract.json, writes the report and skeleton files, and stays behind the smalldpone gitops airflow connection-bridge-planCLI facade.evaluate_connection_bridge_plan_preflightis the release gate helper forGitOpsAirflowPreflightService. It blocks release preflight when requiredAIRFLOW_CONN_*refs exist butconnection-bridge-plan.jsonor required skeleton artifacts are missing or stale.GitOpsAirflowGitSyncPodPatchBuilderbuilds the reusable PodSpec patch:dpone-worktreevolume,dpone-sparse-checkoutinitContainer,dpone-git-syncinitContainer, auth secret mounts/env, base worktree mount, and base working directory.GitOpsAirflowPodContractBuilderturns a bundle, run-spec, runtime profile, and pod options intopod-contract.json,pod-spec.yaml, andkpo-kwargs.jsonwithout importing Airflow or Kubernetes clients.GitOpsAirflowPodDoctorvalidates generated pod contract artifacts, includingbasecontainer drift, PodSpec image drift,pod_template_filedrift,do_xcom_pushdrift, git-sync drift, and Airflow connection bridge drift for runtime-only pods.GitOpsAirflowArtifactIndexBuilderbuilds the deterministicartifact-index.jsoninventory from known Airflow artifact specs. It records expected kind, actual kind, schema version, producer, byte size, and SHA-256 without reading manifests or executing runtime commands.GitOpsAirflowPackPlannerbuilds the publicgitops.airflow_packreport forairflow-runtime-pack.json. It consumes the shared Airflow artifact catalog, normalizes artifact existence/kind/digest evidence, emits deterministic golden-path commands, and separates ordinary plan warnings from verify-mode blockers. It does not parse manifests, mutate PodSpecs, call Airflow, call Kubernetes, or execute subprocesses. The public JSON contract is documented byairflow-pack.schema.json.GitOpsAirflowPreflightServicecomposes the current artifact index, the savedartifact-index.json, registered GitOps schema validation, andGitOpsAirflowPodDoctorService. It owns stale artifact blockers andnext_actions; it must not duplicate pod-doctor checks or mutate PodSpecs.GitOpsAirflowXComOutcomeBuilderconverts runtime evidence into the final XCom summary with status, failed step, evidence SHA-256, step counts, and artifact paths.GitOpsAirflowOutcomeGateEvaluatorevaluates a finalgitops.airflow_xcom_summarypayload for downstream Airflow gates and CI release collectors.GitOpsAirflowArtifactSink,GitOpsAirflowRuntimeResources,GitOpsAirflowRuntimeProfile, andGitOpsAirflowXComSummaryare DTOs for placement, resources, XCom handoff, and release evidence.GitOpsAirflowRunSpecExecutorexecutes run-spec steps through theCommandRunnerprotocol and writes runtime evidence. UseStaticAirflowCommandRunnerin tests; useSubprocessAirflowCommandRunneronly in the custom dpone image.GitOpsAirflowK8sSmokePlannerbuilds an opt-in live smoke contract fromrun-spec.json,runtime-profile.json,pod-contract.json,image-contract.json, andxcom-summary.jsonwithout importing Airflow or Kubernetes clients.GitOpsAirflowClusterDoctorPlannerbuilds the opt-in cluster readiness contract fromruntime-profile.json,pod-contract.json, and optionalconnection-bridge-plan.json. It owns static artifact checks, safe Secret key expectations, ExternalSecret references, and live result policy.AirflowClusterDoctorRunneris the execution port for generated cluster checks. UseStaticAirflowClusterDoctorRunnerin tests andSubprocessAirflowClusterDoctorRunneronly when--mode liveis explicitly selected in a credentialed Airflow/Kubernetes environment.AirflowK8sSmokeRunneris the execution port for generated smoke commands. UseStaticAirflowK8sSmokeRunnerin tests andSubprocessAirflowK8sSmokeRunneronly when--mode liveis explicitly selected in a credentialed Airflow/Kubernetes environment.GitOpsAirflowPodLaunchEvidencePlannerbuilds the reusable pod-watch contract fromruntime-profile.json,pod-contract.json,image-contract.json,runtime-evidence.json, andxcom-summary.json. It normalizes Kubernetes pod, event, and log evidence without importing Airflow or Kubernetes clients.GitOpsAirflowEvidenceBundleCollectorbuilds one release-gradegitops.airflow_evidence_bundlefrom already-emitted JSON artifacts. It owns artifact kind checks, SHA-256 digests, byte sizes, child blocker summaries, and Airflow attempt to Kubernetes pod correlation. It does not read the filesystem and does not execute commands.AirflowPodLaunchEvidenceRunneris the execution port for pod-watch commands. UseStaticAirflowPodLaunchEvidenceRunnerin tests andSubprocessAirflowPodLaunchEvidenceRunneronly when--mode liveis explicitly selected in a credentialed Airflow/Kubernetes environment.GitOpsAirflowRenderServiceowns dependency injection, repo-relative path validation, bundle loading, artifact writing, andgitops.airflow_renderview construction.GitOpsAirflowRunSpecServiceowns runtime contract writing andgitops.airflow_run_specview construction.GitOpsAirflowRuntimeProfileServiceowns runtime profile writing,xcom-summary.jsonwriting, DAG factory writing, andgitops.airflow_runtime_profileview construction.GitOpsAirflowPackServiceowns repo-relative path validation, loading the Airflow artifact directory, writingairflow-runtime-pack.json, andgitops.airflow_packview construction. Keepdpone gitops airflow packas a thin UX orchestrator over existing artifacts; do not add runtime execution, PodSpec reconstruction, manifest discovery, or git-sync auth decisions here.GitOpsAirflowRuntimeProfileOptionsowns parsed runtime-profile CLI options so the runtime-profile service remains orchestration-only.GitOpsAirflowRuntimeProfileGitSyncBuildercomposes git-sync auth options, bundle-derived sparse paths, and required Airflow control artifacts into the optional runtimegit_synccontract.GitOpsAirflowConnectionBridgeBuildercomposes Airflow connection discovery, bridge mode, runtime mode, and Secret/env refs into the optionalconnection_bridgecontract.--airflow-connection-bridge k8s_secretis the default runtime-only path;--airflow-runtime-mode airflow_imageis the explicit custom-image path. Both paths keep Airflow connection values out of generated artifacts by serializing onlyAIRFLOW_CONN_env names and Secret refs.GitOpsAirflowPodContractServiceowns pod contract path validation, artifact loading, PodSpec writing, KPO kwargs writing, andgitops.airflow_pod_contractview construction.GitOpsAirflowPodContractOptionsowns parsed pod-contract CLI options and reserved-name blockers for git-sync volumes and mounts.GitOpsAirflowPodDoctorServiceowns pod contract artifact loading, doctor orchestration, andgitops.airflow_pod_doctorview construction.GitOpsAirflowOutcomeGateServiceowns XCom summary loading, outcome gate orchestration, andgitops.airflow_outcome_gateview construction.GitOpsAirflowEvidenceVerifyServiceowns runtime evidence loading, run-spec loading, verifier orchestration, andgitops.airflow_runtime_evidenceview construction.GitOpsAirflowDoctorServiceowns dependency injection, artifact loading, doctor-policy orchestration, andgitops.airflow_doctorview construction.GitOpsAirflowImageContractServiceowns image contract construction, optional artifact writing, andgitops.airflow_image_contractview construction.GitOpsAirflowK8sSmokeServiceowns artifact loading, path validation, planner orchestration, optional live execution throughAirflowK8sSmokeRunner, andgitops.airflow_k8s_smokeview construction.GitOpsAirflowPodLaunchEvidenceServiceowns artifact loading, path validation, pod-watch planner orchestration, optional live execution throughAirflowPodLaunchEvidenceRunner, andgitops.airflow_pod_launch_evidenceview construction.GitOpsAirflowEvidenceBundleServiceowns repo-relative artifact loading, path validation, the evidence artifact catalog, collector orchestration, andgitops.airflow_evidence_bundleview construction.GitOpsAirflowImageContract,GitOpsAirflowRenderReport,GitOpsAirflowDoctorReport,GitOpsAirflowImageContractReport,GitOpsAirflowRunSpec,GitOpsAirflowRuntimeProfile,GitOpsAirflowRuntimeEvidence,GitOpsAirflowPodContract, andGitOpsAirflowPodDoctorReportare the stable JSON DTOs for CLI, CI, docs, Airflow artifacts, and release gates.GitOpsAirflowOutcomeGateReportis the stable report for downstream XCom gating.GitOpsAirflowPodLaunchEvidenceReportis the stable report for Kubernetes pod phase, imageID, restart, event, and log-tail evidence.GitOpsAirflowEvidenceBundleReportis the stable report for Airflow attempt correlation, Kubernetes pod correlation, and evidence artifact digests.dpone.commands.gitops.airflow_cmdowns the Airflow command group and shared argparse/output rendering for core Airflow commands.dpone.commands.gitops.airflow_k8s_smoke_cmdowns onlyk8s-smokeargparse and rendering so the main Airflow command adapter stays below module-size warning thresholds.dpone.commands.gitops.airflow_pod_launch_evidence_cmdowns onlypod-watchargparse and rendering so the main Airflow command adapter stays below module-size warning thresholds.dpone.commands.gitops.airflow_evidence_bundle_cmdowns onlyevidence-bundleargparse and rendering so attempt evidence collection stays reusable and command handlers remain thin.
Module boundaries¶
dpone.commands.gitops.airflow_cmdanddpone.commands.gitops.airflow_k8s_smoke_cmdanddpone.commands.gitops.airflow_pod_launch_evidence_cmdanddpone.commands.gitops.airflow_pod_cmdanddpone.commands.gitops.airflow_outcome_cmdmust stay thin adapters: parse arguments, call a service, render JSON or Markdown, and write optional output.dpone.services.gitops.airflow_*composes filesystem and YAML ports with domain renderers and validators.dpone.gitops.airflow_runtime_profile_optionsparses runtime-profile CLI options into a small DTO. It owns key/value syntax and repo-relative artifact sink validation so the service stays orchestration only.dpone.gitops.airflow_runtime_profile_pathsnormalizes and validates runtime-profile artifact paths before the service loads or writes files.dpone.gitops.airflow_runtime_profile_git_synccomposes git-sync auth options, bundle-derived sparse paths, and control artifact paths into the optional runtimegit_synccontract.dpone.gitops.airflow_git_sync_artifactsconsumes bundle and plan artifacts to aggregate sparse checkout paths. Missing plan files become blockers only when the profile is being written; Airflow helpers never call this collector directly.dpone.gitops.airflow_pod_contract_optionsparses pod-contract CLI options and owns reserved-name blockers for git-sync volumes and mounts.dpone.gitops.airflow_pod_contract_pathsnormalizes and validates pod-contract artifact paths before the service loads or writes files.dpone.gitops.airflow_json_artifactsowns the small JSON artifact loading and user-facing parse/missing-artifact issues shared by Airflow services.dpone.gitops.airflow_modelsowns public DTOs and JSON contracts.dpone.gitops.airflow_artifactsowns pure rendering with no filesystem, argparse, or scheduler dependency.dpone.gitops.airflow_outcome_gateowns outcome mode normalization and final XCom gate evaluation.dpone.gitops.airflow_runtime_modelsowns run-spec and runtime evidence DTOs.dpone.gitops.airflow_runtime_profile_modelsowns runtime placement, ArtifactSink, resource, and XCom summary DTOs.dpone.gitops.airflow_runtime_profileowns pure runtime-profile building.dpone.gitops.airflow_runtime_profile_policyowns release/advisory runtime-profile decisions.dpone.gitops.airflow_git_sync_modelsowns the optional git-sync DTOs used by runtime-profile, pod-contract, schemas, CLI, docs, and CI gates.dpone.gitops.airflow_connection_bridge_modelsowns the runtime-only Airflow connection bridge DTOs used by runtime-profile, pod-contract, schemas, pod-doctor, docs, and CI gates.dpone.gitops.airflow_connection_bridgeowns manifest-scoped discovery ofconnection_type: airflowids and the bridge policy inputs. It must stay dependency-free with respect to Airflow and Kubernetes clients.dpone.gitops.airflow_connection_bridge_planowns deploy-time Secret, ExternalSecret, and env-example skeleton rendering from a normalizedconnection_bridgecontract. It must not discover manifests or inspect Airflow Connections.dpone.gitops.airflow_connection_bridge_plan_renderingowns Markdown rendering for the bridge plan report only; keep it out ofairflow_renderingto avoid module bloat.dpone.gitops.airflow_git_syncowns pure sparse checkout rendering and PodSpec patch construction for git-sync initContainers. It must not load files, parse argparse, import Airflow, or know manifest dependency rules.dpone.gitops.airflow_pod_contract_modelsowns public pod contract and pod doctor DTOs.dpone.gitops.airflow_pod_contractowns pure PodSpec/KPO kwargs construction.dpone.gitops.airflow_pod_doctorowns reusable pod contract validation.dpone.gitops.airflow_xcom_outcomeowns final XCom outcome construction from runtime evidence.dpone.gitops.airflow_run_specowns pure run-spec construction from a bundle payload.dpone.gitops.airflow_runtime_evidenceowns runtime evidence parsing and verification policy.dpone.gitops.airflow_runtime_executorowns theCommandRunnerprotocol, subprocess-backed runtime execution, and static test runner.dpone.gitops.airflow_k8s_smoke_modelsowns public Airflow Kubernetes smoke DTOs and JSON rendering.dpone.gitops.airflow_k8s_smoke_runnerowns theAirflowK8sSmokeRunnerprotocol, static test runner, and subprocess-backed opt-in live runner.dpone.gitops.airflow_k8s_smokeowns release checks and generated commands, while re-exporting the public smoke names for compatibility. It must stay generic toKubernetesExecutor,KubernetesPodOperator, and KubernetesPodExecutor-style wrappers.dpone.gitops.airflow_pod_launch_evidence_modelsowns public pod-watch command, result, and report DTOs plus JSON rendering.dpone.gitops.airflow_pod_launch_evidence_checksowns the reusable pod-watch check DTO and source taxonomy.dpone.gitops.airflow_pod_launch_evidence_parserowns normalization for Kubernetes pod JSON, event JSON, base container log tail evidence, and observed-pod DTOs.dpone.gitops.airflow_pod_launch_evidence_policyowns artifact checks, release blockers, expected pod phase checks, image digest checks, restart checks, and event blocker checks.dpone.gitops.airflow_pod_launch_evidence_runnerowns theAirflowPodLaunchEvidenceRunnerprotocol, static test runner, and subprocess-backed opt-in live runner.dpone.gitops.airflow_pod_launch_evidenceowns pod-watch planning, command construction, result parsing orchestration, and policy composition. It must stay generic to AirflowKubernetesExecutor,KubernetesPodOperator, KubernetesPodExecutor-style wrappers, and future source -> sink route types.dpone.gitops.airflow_cluster_doctor_models,dpone.gitops.airflow_cluster_doctor_commands,dpone.gitops.airflow_cluster_doctor_runner, anddpone.gitops.airflow_cluster_doctorsplit cluster readiness into DTOs, safe command construction, runner port, and planner policy. Secret checks must list keys only and redact live stdout to expected key names before writing JSON.dpone.services.gitops.airflow_cluster_doctor_serviceloads repo-relative artifacts, extracts ExternalSecret names from generated skeleton files, and composes optional live execution. It must not import Airflow, Kubernetes clients, source/sink connectors, or database SDKs.dpone.gitops.airflow_evidence_bundle_modelsowns public evidence bundle DTOs and JSON rendering for attempt correlation, pod correlation, artifact digests, warnings, and blockers.dpone.gitops.airflow_evidence_bundleowns pure artifact normalization, child evidence status checks, and correlation derivation. It must stay generic to AirflowKubernetesExecutor,KubernetesPodOperator, KubernetesPodExecutor-style wrappers, and future evidence producers.dpone.gitops.schema_airflow_evidence_bundle_contractsowns the public JSON Schema builder forairflow-evidence-bundle.schema.json.dpone.gitops.schema_airflow_git_sync_contractsowns the shared JSON Schema fragment for the runtime-profile and pod-contractgit_syncfield.dpone.gitops.airflow_doctorowns reusable validation policy and emitsGitOpsIssueblockers or warnings.dpone.gitops.airflow_policyowns runner profile names,runner_policynormalization, and profile-specific checks.--runner-policy releasemust stay generic to Airflow/Kubernetes/image-contract posture and must not encode source -> sink route behavior.dpone.gitops.airflow_renderingowns Markdown rendering only.
The pack consumes the existing gitops.bundle contract. It must not duplicate
changed-file resolution, sparse-path discovery, lock verification, or bundle
attestation digest logic. Those rules remain in dpone gitops affected,
dpone gitops plan, dpone gitops verify, and dpone gitops bundle verify.
Extension rules¶
Add a new Airflow artifact by extending GitOpsAirflowArtifactRenderer, adding
a GitOpsAirflowArtifact entry in GitOpsAirflowRenderService, documenting
the file in GitOps Airflow runner pack, and
covering it in tests/test_gitops_airflow_runner_pack.py.
Add a new runtime placement field by extending
GitOpsAirflowRuntimeProfile, GitOpsAirflowRuntimeProfileBuilder, the
dpone gitops airflow runtime-profile parser, airflow-runtime-profile.schema.json,
and both user and developer docs. Keep file paths repo-relative and keep
validation in GitOpsAirflowRuntimeProfilePolicy; do not branch inside CLI
handlers.
Add a new git-sync auth mode by extending GitOpsAirflowGitSyncAuth,
GitOpsAirflowRuntimeProfileGitSyncBuilder,
GitOpsAirflowGitSyncPodPatchBuilder, airflow_git_sync_schema, and both
docs. Serialize only Kubernetes Secret names and key names; never serialize
tokens, private keys, passwords, or local credential file paths. Keep auth
validation in the runtime-profile git-sync builder and reserved pod name
validation in pod-contract options.
Add a new git-sync clone optimization by extending
GitOpsAirflowGitSyncCloneOptions, GitOpsAirflowRuntimeProfileGitSyncBuilder,
GitOpsAirflowGitSyncPodPatchBuilder, airflow_git_sync_schema, and
GitOpsAirflowRuntimeProfilePolicy. Keep version-specific safety in
dpone.gitops.airflow_git_sync_capabilities; do not branch on image tags inside
CLI handlers or Airflow helper code. git-sync:v4.4.0 is sparse-checkout only,
while git-sync:v4.7.0+ supports --filter=blob:none and --filter=tree:0.
The public CLI surface for this contract is --git-sync-repo,
--git-sync-ref, --git-sync-image, --git-sync-auth-mode,
--git-sync-depth, --git-sync-filter, --git-sync-ssh-secret, and
--git-sync-https-secret on dpone gitops airflow runtime-profile. The
supported auth mode values are image, ssh_secret, and https_secret; the
supported partial clone filters are blob:none and tree:0.
Add a new Airflow connection bridge mode by extending
GitOpsAirflowConnectionBridge, GitOpsAirflowConnectionBridgeBuilder,
GitOpsAirflowConnectionBridgePlanBuilder, GitOpsAirflowPodContractBuilder,
airflow_pod_doctor_connection_bridge, the runtime-profile and pod-contract
schemas, airflow-connection-bridge-plan.schema.json, CLI docs, and
user/developer docs. Keep secret values outside all JSON, YAML, Markdown, and
logs. If the mode changes manifest discovery rules, add the rule to
dpone.gitops.airflow_connection_bridge; do not parse manifests inside
generated Airflow DAG helpers. If the deploy-time skeleton changes, update
dpone.gitops.airflow_connection_bridge_plan and the preflight helper instead
of branching in command handlers.
Add a new sparse checkout source by extending
GitOpsAirflowGitSyncArtifactCollector only when the source is already a
rendered dpone control-plane artifact. Do not parse manifest schema in Airflow
helpers; manifest dependency discovery belongs to dpone manifest sparse-paths
and gitops.plan.sparse_paths.
Add a new pod contract option by extending GitOpsAirflowPodContractInput,
GitOpsAirflowPodContractBuilder, the dpone gitops airflow pod-contract
parser, airflow-pod-contract.schema.json, and both docs. Keep repo-owned
paths under safe_relative_path; keep container paths explicit and JSON-safe.
Do not add Airflow SDK imports to the service.
Add a new pod doctor check in GitOpsAirflowPodDoctor when the rule concerns
the generated pod-contract.json, pod-spec.yaml, or kpo-kwargs.json.
Return a GitOpsAirflowCheck plus a blocker or warning. Keep
GitOpsAirflowPodDoctorService limited to loading files and building the view.
Git-sync-specific pod checks belong in dpone.gitops.airflow_pod_doctor_git_sync
so sparse checkout, clone depth, partial clone, worktree mounts, and
initContainer order stay reusable without turning the main doctor into a large
module.
Add a new image contract field by extending GitOpsAirflowImageContract and
GitOpsAirflowImageContractService. Keep the field optional unless every
custom dpone image can populate it. Public outputs must stay repo-relative and
must not expose local absolute paths.
Add a new doctor check in GitOpsAirflowDoctor when it is a reusable
Airflow/Kubernetes contract. Return a check plus a blocker or warning. Do not
raise exceptions for user-facing validation failures, and do not add CLI
branches for validation policy.
Add a new release gate in GitOpsAirflowRunnerPolicyEvaluator when it depends
on the combined runner context or on the selected runner_policy. pr should
prefer warnings; release should fail closed with blockers. Keep
runner_policy in the public gitops.airflow_doctor report.
Add native route tool requirements through the image contract, not through
Airflow-specific code. For example, MSSQL -> ClickHouse can require
clickhouse-client, while Postgres -> MSSQL can require bcp; the runner pack
should still treat both as generic tools entries.
Add a run-spec step by extending GitOpsAirflowRunSpecBuilder. Keep each step
as data: name, kind, command, required, and optional manifest. Do not
add route-specific branches to dpone.commands.gitops.airflow_cmd.
Add runtime evidence checks in GitOpsAirflowRuntimeEvidenceVerifier.
run-spec-exec should write evidence for what happened; evidence-verify
should decide whether the artifact is acceptable for CI or release gates.
Add final XCom outcome fields in GitOpsAirflowXComOutcomeBuilder and
GitOpsAirflowXComSummary. Keep fields additive because Airflow XCom
consumers often parse a subset of the payload. The pod contract keeps the
Airflow return file fixed at /airflow/xcom/return.json; scheduler wrappers
should copy xcom-summary.json there after run-spec-exec exits.
Add outcome gate behavior in GitOpsAirflowOutcomeGateEvaluator and
GitOpsAirflowOutcomeGateService. Keep strict_fail and xcom_then_gate
semantics generic to Airflow XCom delivery, not to a specific source -> sink
route. xcom_then_gate must be documented with a downstream gate because the
pod task exits 0 after writing XCom so Airflow can push the payload.
Add a new Airflow Kubernetes smoke check in GitOpsAirflowK8sSmokePlanner when
the rule can be evaluated from existing artifacts. Add a new live command only
when it is generic to the custom dpone image contract and can be represented as
data in GitOpsAirflowK8sSmokeCommand. Do not add command branching to
dpone.commands.gitops.airflow_cmd; use the AirflowK8sSmokeRunner port for
test doubles and subprocess execution.
Add a new pod launch evidence check in
GitOpsAirflowPodLaunchEvidencePlanner when the rule can be evaluated from
runtime profile, pod contract, image contract, final XCom summary, runtime
evidence, Kubernetes pod JSON, Kubernetes events, or base container logs. Add
new Kubernetes JSON fields in dpone.gitops.airflow_pod_launch_evidence_parser
first, then add policy in the planner. Do not branch in
dpone.commands.gitops.airflow_cmd; use AirflowPodLaunchEvidenceRunner for
test doubles and subprocess execution.
Add a new evidence bundle artifact by extending the artifact catalog in
GitOpsAirflowEvidenceBundleService, then update
GitOpsAirflowEvidenceBundleCollector only when the artifact changes
correlation or pass/fail semantics. Keep artifact paths repo-relative, keep
missing optional artifacts as warnings, and keep release-required artifacts
behind explicit --require-* flags.
Add scheduler-specific examples as generated artifacts or docs. Do not add an Airflow runtime dependency to dpone itself.
JSON contracts¶
dpone gitops airflow render emits gitops.airflow_render with:
bundle_pathoutput_dirimageartifactscommandswarningsblockers
When --require-attestation is set, GitOpsAirflowRenderService and
GitOpsAirflowDoctorService require bundle attestation before Airflow handoff.
This is the release-gate mode for a custom dpone image running under
KubernetesExecutor or KubernetesPodOperator.
dpone gitops airflow doctor emits gitops.airflow_doctor with:
bundle_pathpod_templateimage_contractimagerunner_policycheckswarningsblockers
dpone gitops airflow image-contract emits
gitops.airflow_image_contract with:
output_pathcontractwarningsblockers
The contract object is written to image-contract.json; the report wrapper
is printed to stdout or optional --output.
dpone gitops airflow run-spec emits gitops.airflow_run_spec with:
bundle_pathbundle_digestimageimage_digestworktreeevidence_outputairflow_context_enventriesstepswarningsblockers
dpone gitops airflow runtime-profile emits
gitops.airflow_runtime_profile with:
bundle_pathbundle_digestrun_spec_pathruntime_evidence_pathxcom_summary_pathdag_factory_pathoutcome_gate_pathimageimage_digestnamespaceservice_accountresourcesartifact_sinkenvlabelsannotationsgit_syncrunner_policyoutcome_modewarningsblockers
When the profile passes, GitOpsAirflowRuntimeProfileService writes
runtime-profile.json, xcom-summary.json, airflow_dag_factory.py, and
outcome_gate.py. xcom-summary.json uses gitops.airflow_xcom_summary and
is intentionally small so an Airflow KubernetesPodOperator can push it as
task metadata.
dpone gitops airflow pod-contract emits gitops.airflow_pod_contract with:
bundle_pathrun_spec_pathruntime_profile_pathpod_spec_pathkpo_kwargs_pathimagenamespaceservice_accountxcompod_speckpo_kwargsgit_syncwarningsblockers
When the contract passes, GitOpsAirflowPodContractService writes
pod-contract.json, pod-spec.yaml, and kpo-kwargs.json.
dpone gitops airflow pod-doctor emits gitops.airflow_pod_doctor with:
artifact_dirpod_contract_pathpod_spec_pathkpo_kwargs_pathrunner_policycheckswarningsblockers
The preferred CLI shape is dpone gitops airflow pod-doctor --artifact-dir
.dpone/gitops/airflow --runner-policy release; explicit
--pod-contract-path, --pod-spec-path, and --kpo-kwargs-path flags remain
available for targeted drift debugging.
dpone gitops airflow artifact-index emits and writes
gitops.airflow_artifact_index with:
artifact_diroutput_pathcreated_atentrieswarningsblockers
dpone gitops airflow preflight emits gitops.airflow_preflight with:
artifact_dirartifact_index_pathrunner_policyartifact_indexpod_doctorchecksnext_actionswarningsblockers
dpone gitops airflow connection-bridge-plan emits
gitops.airflow_connection_bridge_plan with:
artifact_diroutput_pathruntime_profile_pathpod_contract_pathmoderuntime_modesecret_namerequired_connection_idsenvartifactswarningsblockers
The report never includes Airflow Connection URI values. For the default
k8s_secret mode, the service writes a Kubernetes Secret skeleton,
ExternalSecret skeleton, and .env.example file with placeholder values only.
Release preflight requires this plan when connection_type: airflow ids are
present in a runtime-only pod contract.
dpone gitops airflow run-spec-exec executes steps and emits
gitops.airflow_runtime_evidence with:
run_spec_pathbundle_pathimagestatusstarted_atfinished_atduration_secondsstepswarningsblockers
It also writes gitops.airflow_xcom_summary to --xcom-output with:
statusruntime_profile_pathrun_spec_pathruntime_evidence_pathruntime_evidence_sha256failed_stepstep_countsartifact_pathsblockers
dpone gitops airflow outcome-gate emits gitops.airflow_outcome_gate with:
xcom_summary_pathrequired_statusstatuspassedrun_spec_pathruntime_evidence_pathruntime_evidence_sha256failed_stepstep_countswarningsblockers
dpone gitops airflow evidence-verify returns the same
gitops.airflow_runtime_evidence shape after adding verification blockers such
as runtime_step_failed, runtime_step_missing, and
runtime_run_spec_path_mismatch.
dpone gitops airflow k8s-smoke emits gitops.airflow_k8s_smoke with:
moderunner_kindrunner_policyrun_spec_pathruntime_profile_pathpod_contract_pathimage_contract_pathxcom_summary_pathnamespaceservice_accountimageimage_digestimage_refsmoke_nametimeout_secondscheckscommandsresultswarningsblockers
mode=plan returns the deterministic command contract without credentials.
mode=live is opt-in live execution through AirflowK8sSmokeRunner; failed
required commands become airflow_k8s_command_failed blockers.
dpone gitops airflow cluster-doctor emits
gitops.airflow_cluster_doctor with:
moderunner_policyartifact_dirruntime_profile_pathpod_contract_pathconnection_bridge_plan_pathnamespaceservice_accounttimeout_secondssecret_refsexternal_secret_refscheckscommandsresultswarningsblockers
mode=plan returns deterministic kubectl get, kubectl auth can-i, Secret
key-listing, and ExternalSecret status commands without credentials.
mode=live is opt-in execution through AirflowClusterDoctorRunner.
Required command failures, RBAC denial, missing Secret keys, and required
ExternalSecret Ready=True drift become release blockers. Secret values must
never appear in results.stdout: secret-key command output is normalized to
the expected key names before serialization.
dpone gitops airflow k8s-manifests emits
gitops.airflow_k8s_manifests with:
artifact_dirmanifest_pathruntime_profile_pathpod_contract_pathconnection_bridge_plan_pathgitops_controllernamespaceservice_accountobjectscontroller_hintswarningsblockers
GitOpsAirflowK8sManifestBuilder is the only owner of Kubernetes object
taxonomy for this feature. It builds deterministic ServiceAccount, Role,
RoleBinding, Secret skeleton, optional ExternalSecret, and optional
NetworkPolicy objects from generated Airflow artifacts.
airflow_k8s_controller_metadata owns the --gitops-controller Argo CD/Flux
metadata policy: plain preserves the historical YAML shape, argocd adds
stable dpone labels and argocd.argoproj.io/sync-wave annotations, and flux
adds stable dpone labels while leaving prune/wait policy to the Flux
Kustomization CR.
GitOpsAirflowK8sManifestsService owns artifact loading, path validation, and
YAML/report writing. Services may serialize the resulting objects to YAML, but
must not mutate Kubernetes object semantics. Secret values are never part of
this contract; generated Secret manifests may name required keys and leave
stringData empty.
dpone gitops airflow admission-check emits
gitops.airflow_admission_check with:
moderunner_policyartifact_dirmanifest_pathpod_spec_pathtimeout_secondscommandsresultswarningsblockers
mode=plan returns deterministic kubectl apply --dry-run=server commands
without credentials. mode=live is opt-in execution through
AirflowAdmissionCheckRunner; failed required dry-run commands become
airflow_admission_command_failed blockers.
GitOpsAirflowAdmissionCheckService owns path validation and runner
injection. Keep this layer Kubernetes client-free: do not import Kubernetes
Python SDKs or Airflow providers.
dpone gitops airflow pod-watch emits
gitops.airflow_pod_launch_evidence with:
moderunner_policyruntime_profile_pathpod_contract_pathimage_contract_pathruntime_evidence_pathxcom_summary_pathpod_namenamespaceservice_accountimageimage_digestexpected_phasetimeout_secondslog_tail_linescheckscommandsresultsobserved_podwarningsblockers
mode=plan returns deterministic kubectl get pod, kubectl get events, and
kubectl logs commands without credentials. mode=live is opt-in execution
through AirflowPodLaunchEvidenceRunner; observed pod phase drift, image
digest drift, non-zero base container exits, restarts, and Kubernetes warning
events become release blockers.
dpone gitops airflow evidence-bundle emits
gitops.airflow_evidence_bundle with:
runner_policyattemptpodartifactswarningsblockers
The attempt object contains dag_id, task_id, run_id, try_number, and
map_index. The pod object contains pod_name, optional pod_uid,
namespace, service account, image, and image digest. Each artifact records the
repo-relative path, expected kind, actual kind, required flag, existence,
SHA-256 digest, byte size, pass/fail state, and reason. Missing required
artifacts, kind drift, failed child statuses, and child blockers fail the
bundle; missing optional artifacts are warnings unless the matching
--require-* flag is set.
Public JSON Schema files live under docs/schemas/gitops/:
airflow-render.schema.jsonairflow-doctor.schema.jsonairflow-image-contract.schema.jsonairflow-run-spec.schema.jsonairflow-runtime-evidence.schema.jsonairflow-runtime-profile.schema.jsonairflow-xcom-summary.schema.jsonairflow-cluster-doctor.schema.jsonairflow-k8s-manifests.schema.jsonairflow-admission-check.schema.jsonairflow-outcome-gate.schema.jsonairflow-pod-contract.schema.jsonairflow-pod-doctor.schema.jsonairflow-connection-bridge-plan.schema.jsonairflow-artifact-index.schema.jsonairflow-preflight.schema.jsonairflow-k8s-smoke.schema.jsonairflow-pod-launch-evidence.schema.jsonairflow-evidence-bundle.schema.json
When a report field changes, update dpone.gitops.schema_contracts, regenerate
or copy the schema file, and extend tests/test_gitops_schema_contracts.py.
The runtime-profile and pod-contract schemas both reuse the shared
airflow_git_sync_schema fragment. This keeps git_sync.enabled, repository
metadata, auth modes, sparse checkout entries, and worktree paths consistent
across the two public contracts.
Runbook¶
- Write failing tests in
tests/test_airflow_runtime_adapter.py,tests/test_gitops_airflow_runner_pack.py,tests/test_gitops_airflow_git_sync_contract.py,tests/test_gitops_airflow_k8s_smoke.py,tests/test_gitops_airflow_pod_launch_evidence.py, andtests/test_cli_gitops_airflow_commands.py. - Keep implementation in the domain/service/command split listed above.
- Update GitOps Airflow runner pack, this
developer guide, architecture docs, CI/CD docs, and generated CLI reference.
Include
--runner-policy release,runner_policy,run-spec.json,runtime-profile.json,pod-contract.json,pod-spec.yaml,kpo-kwargs.json,xcom-summary.json,airflow_dag_factory.py,outcome_gate.py,runtime-evidence.json,airflow-k8s-smoke.json,airflow-cluster-doctor.json,airflow-pod-launch-evidence.json,airflow-evidence-bundle.json,airflow-k8s-manifests.json,airflow-k8s-manifests.yaml,airflow-admission-check.json,artifact-index.json,connection-bridge-plan.json,airflow-connections-secret.yaml,airflow-connections-externalsecret.yaml,airflow-connections.env.example,airflow-artifact-index.schema.json,airflow-connection-bridge-plan.schema.json,airflow-cluster-doctor.schema.json,airflow-k8s-manifests.schema.json,airflow-admission-check.schema.json,airflow-preflight.schema.json, and the Airflow schema file names in docs when policy or schema behavior changes. Ifgit_syncchanges, include sparse git-sync initContainers, auth modes,airflow-dags-devartifact-loading helper UX, and the rule that Airflow must not perform manifest discovery. - Run the focused gate:
uv run pytest tests/test_gitops_airflow_git_sync_contract.py tests/test_gitops_airflow_runner_pack.py tests/test_gitops_airflow_k8s_smoke.py tests/test_gitops_airflow_pod_launch_evidence.py tests/test_cli_gitops_airflow_commands.py tests/test_gitops_airflow_docs_contract.py -q
uv run pytest tests/test_gitops_airflow_k8s_manifests.py tests/test_gitops_airflow_admission_check.py -q
uv run pytest tests/test_gitops_schema_contracts.py -q
uv run dpone docs update-cli-reference --check
uv run dpone docs check-import-rules
uv run dpone docs check-layer-metrics --baseline docs/layer_metrics_baseline.json
uv run dpone docs check-module-size --baseline docs/module_size_baseline.json
- Run the full non-live gate before PR publication.
Quality guardrails¶
- Do not import Airflow or Kubernetes clients into
src/dpone. - Do not execute pods, Docker, manifests, or database connections from render, doctor, runtime-profile, run-spec, image-contract, or evidence-verify services.
- Keep
run-spec-execbehindCommandRunner; tests should useStaticAirflowCommandRunnerand must not launch real source/sink work. - Keep
k8s-smoke --mode livebehindAirflowK8sSmokeRunner; tests should useStaticAirflowK8sSmokeRunner, while normal OSS CI should use--mode plan. - Keep
cluster-doctor --mode livebehindAirflowClusterDoctorRunner; tests should useStaticAirflowClusterDoctorRunner, while normal OSS CI should use--mode plan. - Keep
admission-check --mode livebehindAirflowAdmissionCheckRunner; tests should useStaticAirflowAdmissionCheckRunner, while normal OSS CI should use--mode plan. - Keep Kubernetes manifest rendering behind
GitOpsAirflowK8sManifestBuilder; command and service layers should not branch on individual Kubernetes object internals. - Keep
pod-watch --mode livebehindAirflowPodLaunchEvidenceRunner; tests should useStaticAirflowPodLaunchEvidenceRunner, while normal OSS CI should use--mode plan. - Keep final XCom outcome construction behind
GitOpsAirflowXComOutcomeBuilderso scheduler helpers do not parse runtime evidence internals. - Keep downstream gate decisions behind
GitOpsAirflowOutcomeGateEvaluatorso scheduler helpers can consume final XCom summaries without understanding run-spec internals. - Keep sparse git-sync construction behind
GitOpsAirflowGitSyncPodPatchBuilderandGitOpsAirflowRuntimeProfileGitSyncBuilder. Airflow helpers should consumekpo-kwargs.jsonandpod-spec.yaml; they must not compute sparse paths, inspect manifests, choose auth modes, or mutate initContainers. - Keep git-sync secret handling name/key-only in public artifacts. Secret values belong in Kubernetes Secrets and must never appear in JSON, YAML, Markdown, test fixtures, or logs.
- Do not emit local absolute paths in public JSON or Markdown.
- Keep command handlers thin; validation belongs in
GitOpsAirflowDoctor. - Keep generated artifacts deterministic so CI, release gates, and Airflow task logs can compare them across runs.