Why
Flux controllers persist a small rolling reconciliation/release history directly on the CR in status.history. This is useful for operators debugging “what changed, when, and did it work?” without digging through events/logs.
I want to add an experimental UI in Capacitor to render this history so we can validate whether it is useful in day-to-day app operations.
Reference implementation/inspiration: flux-operator web UI history timeline + navigation fix:
Data source (no new backend required)
Capacitor already watches/loads Flux resources; the history is part of the watched object JSON.
Kustomization
kustomize.toolkit.fluxcd.io/Kustomization
status.history[] entries typically contain:
digest, firstReconciled, lastReconciled, lastReconciledDuration, lastReconciledStatus, totalReconciliations
metadata.revision (+ sometimes metadata.originRevision)
HelmRelease
helm.toolkit.fluxcd.io/HelmRelease
status.history[] entries typically contain:
version, status (e.g. deployed / superseded), firstDeployed, lastDeployed
chartName, chartVersion, optional appVersion
digest, configDigest, optional ociDigest
Proposed UX (mockup)
Kustomization details: add a “History” tab
Render newest-first.
Row content
- Outcome badge: derived from
lastReconciledStatus (Succeeded / Failed / Other)
- Time:
lastReconciled (and optionally range firstReconciled → lastReconciled when different)
- Duration:
lastReconciledDuration
- Reconciliations count:
totalReconciliations
- Revision:
metadata.revision (clickable when source is GitRepository + SHA present, similar to existing revision rendering)
- Digest:
digest (shortened, copy button)
Example:
Reconciliation history (last 5 snapshots stored by controller)
[✓ Succeeded] 2026-02-08 10:24:12Z duration: 12.4s reconciliations: 397
Revision: main@sha1:b070466
Digest: sha256:d8fc4a3a7b06…
[✗ HealthCheckFailed] 2026-02-08 09:59:01Z duration: 2m10s reconciliations: 396
Revision: main@sha1:a8c1d2e
Digest: sha256:91ad0c2f0f88…
HelmRelease details: add a “History” tab
Prefer HelmRelease.status.history (CR-based) for an MVP (no Helm storage access required).
Row content
- Status badge: from
status (deployed / superseded / etc.)
- Revision:
version
- Updated:
lastDeployed
- Chart:
${chartName}@${chartVersion}
- App Version:
appVersion (if present)
- Values/Config fingerprint:
configDigest (shortened, copy button)
Example:
Release history (last ~5 snapshots stored by controller)
[✓ deployed] rev: 42 2026-02-08 10:12:09Z
Chart: tailscale-operator@1.2.3 App: 0.9.1
Config digest: sha256:1a2b3c4d…
[• superseded] rev: 41 2026-02-07 18:44:31Z
Chart: tailscale-operator@1.2.2 App: 0.9.0
Implementation notes
- Add a small reusable component (e.g.
HistoryTimeline or HistoryList) that supports two schemas:
- Kustomization-style:
firstReconciled/lastReconciled/lastReconciledStatus/totalReconciliations/metadata.revision
- HelmRelease-style:
firstDeployed/lastDeployed/status/version/chartVersion/appVersion/configDigest
- Reset/avoid stale UI state when navigating between resources (see flux-operator PR #532).
- Mark as Experimental (feature flag in config, env var, or hidden behind an “Experimental” toggle).
Acceptance criteria
Out of scope (for the first iteration)
- Correlating history entries with Events/logs
- Showing full diffs between digests
- Anything that requires extra cluster permissions beyond reading the CR
Why
Flux controllers persist a small rolling reconciliation/release history directly on the CR in
status.history. This is useful for operators debugging “what changed, when, and did it work?” without digging through events/logs.I want to add an experimental UI in Capacitor to render this history so we can validate whether it is useful in day-to-day app operations.
Reference implementation/inspiration: flux-operator web UI history timeline + navigation fix:
Data source (no new backend required)
Capacitor already watches/loads Flux resources; the history is part of the watched object JSON.
Kustomization
kustomize.toolkit.fluxcd.io/Kustomizationstatus.history[]entries typically contain:digest,firstReconciled,lastReconciled,lastReconciledDuration,lastReconciledStatus,totalReconciliationsmetadata.revision(+ sometimesmetadata.originRevision)HelmRelease
helm.toolkit.fluxcd.io/HelmReleasestatus.history[]entries typically contain:version,status(e.g.deployed/superseded),firstDeployed,lastDeployedchartName,chartVersion, optionalappVersiondigest,configDigest, optionalociDigestProposed UX (mockup)
Kustomization details: add a “History” tab
Render newest-first.
Row content
lastReconciledStatus(Succeeded / Failed / Other)lastReconciled(and optionally rangefirstReconciled → lastReconciledwhen different)lastReconciledDurationtotalReconciliationsmetadata.revision(clickable when source is GitRepository + SHA present, similar to existing revision rendering)digest(shortened, copy button)Example:
HelmRelease details: add a “History” tab
Prefer
HelmRelease.status.history(CR-based) for an MVP (no Helm storage access required).Row content
status(deployed/superseded/ etc.)versionlastDeployed${chartName}@${chartVersion}appVersion(if present)configDigest(shortened, copy button)Example:
Implementation notes
HistoryTimelineorHistoryList) that supports two schemas:firstReconciled/lastReconciled/lastReconciledStatus/totalReconciliations/metadata.revisionfirstDeployed/lastDeployed/status/version/chartVersion/appVersion/configDigestAcceptance criteria
status.historyexists, otherwise show “No history available”.status.historyexists, otherwise show “No history available”.Out of scope (for the first iteration)