Skip to content

docs(gitops): two source-of-truth modes design (K2)#152

Merged
astrojerms merged 1 commit into
mainfrom
docs/k2-gitops-modes
Jul 20, 2026
Merged

docs(gitops): two source-of-truth modes design (K2)#152
astrojerms merged 1 commit into
mainfrom
docs/k2-gitops-modes

Conversation

@astrojerms

Copy link
Copy Markdown
Owner

K2 — GitOps two-mode design (first step)

The roadmap's K2 says: "Write the invariants down first (short design doc), then reconcile the code to them." This is that doc — docs/gitops-modes.md. No code change; it de-risks the eventual reconciliation of the metal-critical reconcile/mirror paths.

The problem

git-as-source (B1–B3: pull/prune/webhook) was layered on git-as-sink (disk mirror + auto-commit + push), and the two can both be on and conflict:

  1. Startup re-materialize fights prune — a pruned resource's mirror file reappears from SQLite and the resource comes back.
  2. --ff-only pull fights auto-commit — a local auto-commit diverges history so the next pull fails.

The design

Two explicit, non-overlapping modes, one switch (manifests.mode: mirror|gitops), only the chosen mode's machinery runs:

mirror (default) gitops
truth SQLite the repo
git read-only audit mirror the input
auto-commit / push yes no
startup revive missing files yes no
pull / prune / webhook / file→apply no yes
drift reconciler yes yes (mode-agnostic)

Both conflicts are resolved by the invariants (gitops: no auto-commit, no startup-revive). Prune's safety now rests on K3's durable source column (shipped), not the GC-able ops table.

The doc also specifies the config surface + contradictory-combo rejection, back-compat (default mirror, existing manifests.git-only configs unchanged), a per-component code-reconciliation checklist, and a test plan (incl. asserting both conflicts can't occur).

Follow-up (tracked in ROADMAP)

The code reconciliation itself — best paired with real homelab validation of both modes. The open "which mode is the recommended default" question ties to K5 (scope), but the mechanism here is independent of that call.

Docs only — no Go changes.

Add docs/gitops-modes.md — the prescribed first step of K2: fix the
invariants for collapsing the overlapping git-as-sink + git-as-source
machinery into two explicit, non-overlapping modes before touching code.

- mirror (default): SQLite is truth, git is a read-only audit mirror
  (materialize + auto-commit + push + startup-revive; no pull/prune/webhook).
- gitops: the repo is truth (pull/apply/prune/webhook + local file→apply;
  NO auto-commit of desired specs, NO startup file-revival).

Fixes the two known conflicts (startup re-materialize vs prune; --ff-only
pull vs auto-commit) via the invariants, defines the `manifests.mode`
switch + contradictory-combo rejection, back-compat (default mirror), a
per-component code-reconciliation checklist, and a test plan. Notes the
drift reconciler is mode-agnostic and prune trusts K3's source column.

The code reconciliation is a separate follow-up (tracked), best paired
with homelab validation of both modes.
@astrojerms
astrojerms merged commit 72b719c into main Jul 20, 2026
6 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant