🤖 Generated by the Agentic Engineer
Evidence
#112 restored the repository write path (#136, merged 2026-08-06T01:37:50Z, artifact 1.22.1). Every resource that attempted an update afterwards succeeded:
| Repository |
LastAsyncOperation after the fix |
aws |
Success 2026-08-06T01:39:11Z |
doggy-countdown |
Success 01:39:09Z |
kyverno-policies |
Success 01:39:11Z |
provider-upjet-unifi |
Success 01:39:10Z |
Three did not, and still report ReconcileError with the old 422 message:
| Repository |
last update attempt |
age at 2026-08-06 |
agent-skills |
2026-07-20T00:32:52Z |
17 days |
platform-tenant-template |
2026-08-02T18:54:05Z |
3 days |
agent-plugins |
2026-08-03T19:45:36Z |
2 days |
Problem
The Synced message on these three is the cached result of that old attempt, not a fresh rejection — the underlying cause it names was fixed and demonstrably no longer rejects anyone else. They are not being rejected; they are not trying.
That matters beyond these three repositories: it means a resource can enter a state where fixing the root cause is not enough to recover it, and the stale condition message actively misleads whoever looks — it points at a cause that is already resolved. Any future repository-settings failure can strand a resource the same way.
⚠️ Synced.lastTransitionTime is rewritten roughly every 60s whether or not anything happened, so it cannot be used to tell a fresh failure from a stale one. Use LastAsyncOperation.lastTransitionTime, which only moves when an operation actually completes.
Observation worth checking first
The three carry only the crossplane.io/external-name annotation. Healed resources such as kyverno-policies also carry crossplane.io/external-create-pending, crossplane.io/external-create-succeeded and crossplane.io/external-create-failed. Whether that is the cause or a side effect of the same history is unverified — it is the first thing to test, not a conclusion.
Suggested approach
- Establish why no reconcile issues an update: a stuck async-operation record, an exponential backoff that has grown unbounded, or the resource being considered up to date while the condition says otherwise.
- Prefer a fix that recovers automatically. A manual nudge (annotation bump, provider restart) may confirm the diagnosis, but a resource that cannot self-recover from a transient provider error is the actual defect.
- Establish whether a bounded retry or a staleness check on
LastAsyncOperation belongs in the repository-update contract, so a wedged resource is visible rather than silently frozen behind a stale message.
Acceptance criteria
Blocks #112, which stays open until 20/20 is observed.
Evidence gathered live against admin@prod; no cluster mutation was performed, deliberately, so the stuck state remains available for diagnosis.
Evidence
#112 restored the repository write path (#136, merged 2026-08-06T01:37:50Z, artifact
1.22.1). Every resource that attempted an update afterwards succeeded:LastAsyncOperationafter the fixawsdoggy-countdownkyverno-policiesprovider-upjet-unifiThree did not, and still report
ReconcileErrorwith the old 422 message:agent-skillsplatform-tenant-templateagent-pluginsProblem
The
Syncedmessage on these three is the cached result of that old attempt, not a fresh rejection — the underlying cause it names was fixed and demonstrably no longer rejects anyone else. They are not being rejected; they are not trying.That matters beyond these three repositories: it means a resource can enter a state where fixing the root cause is not enough to recover it, and the stale condition message actively misleads whoever looks — it points at a cause that is already resolved. Any future repository-settings failure can strand a resource the same way.
Synced.lastTransitionTimeis rewritten roughly every 60s whether or not anything happened, so it cannot be used to tell a fresh failure from a stale one. UseLastAsyncOperation.lastTransitionTime, which only moves when an operation actually completes.Observation worth checking first
The three carry only the
crossplane.io/external-nameannotation. Healed resources such askyverno-policiesalso carrycrossplane.io/external-create-pending,crossplane.io/external-create-succeededandcrossplane.io/external-create-failed. Whether that is the cause or a side effect of the same history is unverified — it is the first thing to test, not a conclusion.Suggested approach
LastAsyncOperationbelongs in the repository-update contract, so a wedged resource is visible rather than silently frozen behind a stale message.Acceptance criteria
Repositoryresources reportReconcileSuccess.Blocks #112, which stays open until 20/20 is observed.
Evidence gathered live against
admin@prod; no cluster mutation was performed, deliberately, so the stuck state remains available for diagnosis.