0011 — Resource identity: UID, generation, and revision
- Status: accepted
- Date: 2026-08-06
- Owners: Takoform maintainers
Context
The v1alpha2 wire duplicates naming and versioning concerns: metadata.name, spec.name, a provider name attribute, output.name, observed.id, and output.id coexist; resourceVersion acts both as the desired-state generation and as the strong ETag for the whole representation, even though observe/refresh legitimately change status without changing desired state. Form Definitions also each re-declare envelope facts (observed.ready, observed.generation, output.id, portability markers) that belong to the protocol, not to any one Form. Finally, provider state keys resources by packageDigest in addition to FormRef, so the same resource read through a different — equally valid — package of the same Form becomes unaddressable.
Decision
The v1alpha3 resource envelope owns identity and versioning; Form schemas own only portable desired fields.
metadata.nameis the only name.spec.nameand per-Form envelope fields (/name,observed.id,observed.generation,observed.ready,output.id,output.name, and similar) are removed from Form Definitions.metadata.uidis a host-issued immutable identity. Deleting and recreating a same-named resource yields a different UID. Mutations may carry an expected UID and are rejected on mismatch.metadata.generation(canonical decimal string) increments only when the portable desired spec changes.metadata.revision(canonical decimal string) increments whenever the full representation — including status and outputs — changes. The HTTP strong ETag is the quoted revision.status.observedGenerationstates which desired generation the status reflects.status.conditionsuses the closed setReady,Reconciling,Degraded,Drifted,Blocked,Deletingwith closed portable reasons; host-internal codes go to a separatehostReason.- Desired-state mutations fence on the expected generation; representation fences use
If-Matchon the revision. Stale fences fail withgeneration_conflict(412) orrevision_conflict(412). - The Form semantic identity of a resource is its exact FormRef. The package digest used at creation may be recorded as audit evidence but never enters resource identity, queries, or update/delete fences. A host that installed the same FormRef from a different legitimate package must read and delete the same resource.
Consequences
- Provider v2.1 family-resource state identity is
space,apiVersion,kind,uid; a JSON-serializedstatus.outputsdocument (outputs_json) replaces the string-map outputs; the ETag/generation split removes the global client-side mutation mutex. - Conformance gains UID-stability, delete/recreate UID change, generation-only-on-spec-change, revision-on-status-change, stale-fence rejection, and package-digest-substitution checks.
- Form authoring gets simpler: definitions stop repeating envelope plumbing.
Rejected alternatives
- Keep one
resourceVersionfor both fences. Rejected because observe/refresh then either lies (status changes invisible to ETag) or breaks desired-state fencing (every observe invalidates client fences). - Key state by
space/nameonly. Rejected because delete/recreate would silently rebind old state to a new resource; UID makes that visible. - Keep
packageDigestin identity for provenance. Rejected because provenance is evidence, not identity; it is retained as an audit field.