Files
aios/docs/gitops/durable-job-controller.md
T

1.9 KiB

Durable GitOps Job Controller

The control-plane write boundary is a durable Job, not a synchronous checkout or commit request. The source of truth is SQLite WAL at /var/lib/aios-gitops/jobs/state.sqlite3, with jobs, idempotency_keys, branch_leases, state_transitions, and receipts tables. Per-job request.json, state.json, receipts/, and logs-digest/ files are durable mirrors/evidence, not a second state machine.

The controller owns only binding validation, idempotency, state transitions, and recovery classification. A supervised worker owns an isolated detached worktree and all Git side effects. /api/file and /api/commit-file adapters must return job_id and side_effect_state; they must never perform checkout, file write, git add, or git commit inline.

/var/lib/aios-gitops/payloads/sha256/<digest> is the content-addressed payload store. SQLite records only payload_digest, payload_ref, and size; the worker verifies both digest and size before consumption. The durable execution gate is AIOS_GITOPS_DURABLE_JOB_EXECUTION_ENABLED=true, while AIOS_GITOPS_WRITES_ENABLED=false remains the independent legacy repository mutation gate.

The idempotency key is the SHA-256 of the canonical tuple:

campaign_id, repository, operation, branch, expected_branch_oid, and payload_digest.

The writer lease is CONTINUE_EXISTING for the recovered campaign. It binds to lineage anchor 69b45e81dcd2c3707c367003b08c55fd361faae8 and exact initial head bba675fab3b7e0c5fba7066720252b3c91b9f20d. Every ref update is delegated to a non-Owner machine broker using compare-and-swap; a stale head is a BRANCH_LEASE_STALE condition and never a force push.

Production remains outside this worker contract. The fixed aios-gitops-writer.service uses Accept=no, automatic restart, and durable queue/reconciliation execution; it cannot mutate Git while the legacy global write gate is false or while the campaign/machine capability is absent.