GitOps control plane¶
dpone gitops affected, dpone gitops bundle, dpone gitops plan, and
dpone gitops verify turn manifest dependency metadata into reviewable runner
contracts for sparse checkout systems.
Use this layer when Airflow, KubernetesPodOperator, GitHub Actions, Dagster,
Argo, or a shell runner should fetch only the files required for one workload
and then run a deterministic dpone command.
The GitOps control plane does not execute manifests, call Git, import Airflow, open database connections, or mutate runtime state. It builds and verifies plain JSON or Markdown artifacts.
Quickstart¶
Create a plan:
dpone gitops plan dpone_workloads/manifests/mssql/orders.yaml \
--include-env-overrides dev \
--include-registry \
--support-path dpone_workloads/sql/orders/ \
--runner kubernetes_pod_operator \
--run-command "dpone run dpone_workloads/manifests/mssql/orders.yaml" \
--output .dpone/gitops/orders/gitops_plan.json
Verify a sparse worktree before the runner executes:
dpone gitops verify .dpone/gitops/orders/gitops_plan.json \
--worktree . \
--verify-lock \
--output .dpone/gitops/orders/gitops_verify.json
Both commands print to stdout and can also write the same artifact to
--output. Use --format markdown for human review comments and --format
json for CI gates.
Find impacted manifests from a Git diff:
dpone gitops affected \
--from-ref origin/master \
--to-ref HEAD \
--include-env-overrides dev \
--include-registry \
--support-path dpone_workloads/sql/orders/ \
--runner kubernetes_pod_operator \
--emit-plans \
--output .dpone/gitops/affected.json
dpone gitops affected scans manifest entrypoints under the workload root,
builds their sparse-path reports, and returns only the manifests whose
allowlists intersect the changed repo-relative files. With --emit-plans, it
writes a gitops_plan.json artifact for every impacted manifest under
.dpone/gitops/affected/.
Changed files can come from --changed-files, a newline-delimited
--changed-files-file, or git diff --name-only via --from-ref and
--to-ref. The inputs are deduplicated in first-seen order before impact
analysis.
Build a complete scheduler handoff bundle:
dpone gitops bundle \
--from-ref origin/master \
--to-ref HEAD \
--include-env-overrides dev \
--include-registry \
--support-path dpone_workloads/sql/orders/ \
--runner kubernetes_pod_operator \
--policy-profile release \
--attest \
--output-dir .dpone/gitops/bundle \
--output .dpone/gitops/bundle.json
dpone gitops bundle is the highest-level GitOps control-plane command. It
uses the same changed-file inputs as dpone gitops affected, emits a
gitops.plan for every impacted manifest, verifies each emitted plan, and
writes one deterministic handoff directory:
.dpone/gitops/bundle/
affected.json
bundle.json
summary.md
manifests/<manifest-slug>/gitops_plan.json
manifests/<manifest-slug>/gitops_verify.json
Use the policy flags when CI should fail closed before a scheduler starts:
--policy-profile advisorykeeps the bundle informational.--policy-profile prenables lock verification and empty-impact blocking for pull-request gates while keeping warnings reviewable.--policy-profile releaseenables lock verification, empty-impact blocking, warning blocking, and required lock verification for release gates.--fail-on-empty-impactreturns anempty_impactblocker when the changed files do not map to any manifest.--fail-on-warningsreturns awarnings_presentblocker when dependency discovery, changed-file resolution, or verification produced warnings.--require-lockrequires--verify-lockand returnslock_verification_requiredif lock verification is not enabled.--attestembeds a SHA-256 attestation inbundle.json.
The bundle JSON is safe to store as a CI artifact or pass to Airflow,
KubernetesPodOperator, GitHub Actions, Dagster, Argo, or a shell runner. It
contains repo-relative paths only: output_dir, affected_path,
summary_path, per-manifest plan_path, per-manifest verify_path,
warnings, blockers, the active policy profile, and optional attestation
evidence.
When --attest is enabled, bundle.json.attestation contains:
schema_version,producer, andhash_algorithm;- sanitized provenance such as
from_ref,to_ref, changed files, runner, policy profile, and output directory; - artifact digests for
affected.json, eachgitops_plan.json, eachgitops_verify.json, andsummary.md; bundle_digest, a stable SHA-256 digest over the artifact digest records.
The attestation intentionally excludes bundle.json from the digest set to
avoid circular self-hashing. Store bundle.json with runner logs and release
evidence so downstream systems can prove which files were planned and verified.
Verify a stored bundle before a scheduler or release finalizer consumes it:
dpone gitops bundle verify is an offline integrity check. It reads the
repo-relative bundle.json, validates the public bundle contract, recomputes
attested artifact SHA-256 digests and byte sizes, recomputes bundle_digest,
and returns blockers when any artifact is missing or drifted. Use
--require-attestation for release gates where a bundle without digest evidence
must fail closed. Without --require-attestation, missing attestation is a
warning so older advisory bundles can still be inspected.
Public JSON Schema files are shipped in docs/schemas/gitops/ and listed in
the generated GitOps schema catalog.
Validate catalog entries and payloads without Airflow or runtime imports:
dpone gitops schema list
dpone gitops schema show dpone.release-set.v1
dpone gitops schema validate --kind dpone.safe-sample-runtime-run.v1 --payload runtime-run.json
Legacy human-maintained contract groups include:
affected.schema.jsonplan.schema.jsonverify.schema.jsonbundle.schema.jsonattestation.schema.jsonairflow-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-run-identity.schema.jsonairflow-rerun-plan.schema.jsonairflow-cluster-doctor.schema.jsonairflow-k8s-manifests.schema.jsonairflow-admission-check.schema.jsonairflow-pack.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
These JSON Schema contracts describe stable fields for external CI, Airflow,
KubernetesPodOperator, Dagster, and release tooling. They are intentionally
additive: consumers should accept unknown fields and require only the documented
stable contract fields.
Airflow Kubernetes runner pack¶
Use GitOps Airflow runner pack when Airflow
should run a custom dpone image through KubernetesExecutor,
KubernetesPodOperator, or KubernetesPodExecutor-style wrappers. The command
family adds self-service helpers on top of gitops.bundle:
dpone gitops airflow image-contract --image ghcr.io/acme/dpone:2026.06.16 --tool dpone
dpone gitops airflow render .dpone/gitops/bundle/bundle.json --image ghcr.io/acme/dpone:2026.06.16 --require-attestation
dpone gitops airflow run-spec .dpone/gitops/bundle/bundle.json --image ghcr.io/acme/dpone:2026.06.16 --require-attestation
dpone gitops airflow runtime-profile .dpone/gitops/bundle/bundle.json --image ghcr.io/acme/dpone:2026.06.16 --run-spec-path .dpone/gitops/airflow/run-spec.json --runner-policy release
dpone gitops airflow run-spec-exec .dpone/gitops/airflow/run-spec.json --evidence-output .dpone/gitops/airflow/runtime-evidence.json
dpone gitops airflow k8s-manifests --artifact-dir .dpone/gitops/airflow --gitops-controller argocd --manifest-output .dpone/gitops/airflow/airflow-k8s-manifests.yaml
dpone gitops airflow admission-check --artifact-dir .dpone/gitops/airflow --mode plan --runner-policy release
dpone gitops airflow pack --artifact-dir .dpone/gitops/airflow --mode verify --runner-policy release
dpone gitops airflow outcome-gate .dpone/gitops/airflow/xcom-summary.json --required-status passed
dpone gitops airflow evidence-verify .dpone/gitops/airflow/runtime-evidence.json --run-spec-path .dpone/gitops/airflow/run-spec.json --require-all-steps
dpone gitops airflow evidence-bundle --dag-id dpone_gitops --task-id dpone_orders --run-id manual__2026-06-16T10:00:00+00:00 --try-number 1 --require-k8s-smoke --require-pod-launch-evidence
dpone gitops airflow doctor .dpone/gitops/bundle/bundle.json --pod-template .dpone/gitops/airflow/pod_template.yaml --image-contract .dpone/gitops/airflow/image-contract.json --require-attestation
The renderer writes pod_template.yaml, executor_config.json,
airflow_task.py, entrypoint.sh, run-spec.json, runtime-profile.json,
xcom-summary.json, airflow_dag_factory.py, outcome_gate.py, and
image-contract.json. The runtime adapter writes runtime-evidence.json and
the final XCom outcome. The outcome gate checks that XCom status is
passed before a downstream Airflow task or release collector marks the run
successful. The doctor checks bundle
attestation, pod_template_file requirements, the Airflow base container
contract, image contract consistency, runner_policy, and
--runner-policy release hardening checks before the scheduler starts a pod.
The evidence verifier checks the pod result after the custom dpone image exits.
The evidence-bundle collector then correlates dag_id, task_id, run_id,
try_number, map_index, pod name, optional pod UID, and SHA-256 digests for
bundle.json, run-spec.json, runtime-profile.json, pod-contract.json,
runtime-evidence.json, xcom-summary.json, airflow-k8s-smoke.json, and
airflow-pod-launch-evidence.json into airflow-evidence-bundle.json.
artifact-index.json records the deploy-time artifact inventory,
airflow-runtime-pack.json records the top-level golden-path command and
artifact checklist, and dpone gitops airflow preflight checks schema
validity, stale artifact digests, pod-doctor output, and release-policy
next_actions before Airflow consumes the pack.
What the plan contains¶
The plan embeds:
- the root manifest and inferred workload root;
- the sparse checkout allowlist from
dpone manifest sparse-paths; - a runner family such as
generic,airflow, orkubernetes_pod_operator; - the command the runner should execute after checkout;
- warnings and blockers from sparse-path discovery;
- a provenance block with the GitOps plan schema version;
- a lock block with repo-relative paths and SHA-256 digests for file entries.
The sparse paths remain repo-relative. Public output does not expose local absolute filesystem paths.
The lock is intentionally lightweight: directories and missing optional paths
are recorded with sha256: null, while present files get a deterministic
digest. Runners can persist the lock next to task logs to prove which manifest
and support files were planned at handoff time.
Use dpone gitops verify --verify-lock when a runner must prove that file
contents still match the plan. Digest mismatches and missing locked files are
blockers; directory entries and lock entries without a digest are warnings
because there is no stable file hash to compare.
Runner handoff¶
A KubernetesPodOperator or similar runner should treat the JSON plan as the
contract:
- checkout the repository;
- apply the plan's
sparse_pathsallowlist; - run
dpone gitops verify <plan> --worktree <checkout>; - execute the plan's
command.textonly when verification exits0; - store the plan and verify artifacts with task logs.
Runner code should not know dpone manifest internals. If a new manifest field starts referencing files, add that field to dpone's dependency rule catalog instead of duplicating schema logic in scheduler code.
For CI systems that need one artifact instead of per-manifest orchestration,
use dpone gitops bundle first and hand entries[*].plan_path to downstream
runner tasks. The runner should still run dpone gitops verify inside the
sparse checkout before dpone run.
Impact planning runbook¶
Use dpone gitops affected in CI when a scheduler wants to start only the
workloads touched by a pull request:
- collect changed repo-relative paths from Git, a CI file, or refs;
- run
dpone gitops affected --from-ref origin/master --to-ref HEAD; - review
impacted_manifests[*].reasonsto see why each manifest matched; - optionally enable
--emit-plansand publish the emitted plan artifacts; - hand the emitted plan path to Airflow,
KubernetesPodOperator, Dagster, or another runner; - run
dpone gitops verifyinside the sparse checkout beforedpone run.
Invalid changed paths, such as absolute paths or .., fail closed with
blockers. Missing dependency files remain warnings so GitOps output stays
deterministic during branch creation.
Bundle policy runbook¶
Use dpone gitops bundle when CI should publish a complete handoff pack:
- collect changed paths from
--changed-files-fileor Git refs with--from-refand--to-ref; - include the same overrides, registries, and support paths that the runner will need;
- use
--policy-profile prfor pull-request gates or--policy-profile releasefor release gates; - add
--attestwhen the bundle should carry artifact digest evidence; - run
dpone gitops bundle verify <bundle.json> --require-attestationbefore scheduler handoff or release promotion; - enable
--verify-lockdirectly only when using--policy-profile custom; - add
--fail-on-empty-impactfor pull-request gates that must prove the change either affects a workload or is intentionally ignored; - add
--fail-on-warningsfor release gates where unresolved group dependencies or missing optional paths must be reviewed before merge; - add
--require-lockwhen digest verification is mandatory; - publish
bundle.json,affected.json, per-manifest plan/verify JSON, andsummary.mdas CI artifacts.
The command writes artifacts even when policy blockers are present. This keeps debugging self-service: CI can fail the job while still exposing the exact changed files, impacted manifests, warnings, blockers, and plan paths.
Runbook¶
- Generate a plan locally and review
warnings. - Commit the manifest, support assets, and plan wiring in the same pull request.
- In CI, run
dpone gitops verifyafter sparse checkout and before runtime execution. - Treat
blockersas fail-closed. Treatwarningsas review items unless your deployment policy escalates them. - Keep
--support-pathexplicit for SQL, templates, or scripts until those files have first-class manifest dependency fields.
Common fixes¶
| Symptom | Fix |
|---|---|
missing_required_path blocker |
Add the file to the repository or include the correct support path. |
missing_optional_path warning |
Create the optional override or leave the deterministic future path. |
invalid_plan_path blocker |
Remove absolute paths, .., or empty path segments from the plan. |
invalid_changed_path blocker |
Pass repo-relative Git paths only to dpone gitops affected. |
changed_files_missing blocker |
Provide --changed-files, --changed-files-file, or --from-ref with --to-ref. |
lock_digest_mismatch blocker |
Regenerate the plan or investigate why the file changed after planning. |
empty_impact blocker |
Remove --fail-on-empty-impact for advisory runs or confirm the change should not launch workloads. |
warnings_present blocker |
Resolve warnings or move the run to an advisory policy without --fail-on-warnings. |
lock_verification_required blocker |
Add --verify-lock when --require-lock is enabled. |
| Missing attestation | Add --attest and publish the resulting bundle.json with CI artifacts. |
artifact_digest_mismatch blocker |
Regenerate the bundle or investigate artifact drift after planning. |
bundle_digest_mismatch blocker |
Regenerate the bundle; at least one attested artifact digest no longer matches the bundle digest. |
| Runner checks out too much | Prefer plan sparse paths over hand-maintained scheduler allowlists. |