This document is the oci-service-operator-6kv.2 contract for the shared
async status surface published by OSOK CRDs.
The shared async tracker now lives at:
.status.status.async.current.source.status.status.async.current.phase.status.status.async.current.workRequestId.status.status.async.current.rawStatus.status.status.async.current.rawOperationType.status.status.async.current.normalizedClass.status.status.async.current.percentComplete.status.status.async.current.message.status.status.async.current.updatedAt.status.status.opcRequestIdThe schema is OSOK-owned. Public status never exposes provider SDK enum types;
raw provider values are preserved only as plain strings in rawStatus and
rawOperationType.
Each published CR embeds shared.OSOKStatus under the resource-specific
status field named status, so the shared tracker is exposed on the CR at
.status.status.async.current.workRequestId. Within the embedded shared
status object itself, status.async.current.workRequestId is the canonical
field name, and status.opcRequestId is the canonical OCI request-correlation
field.
status.opcRequestId means: the latest non-empty OCI request ID from a
create, update, or delete response header, or from a surfaced OCI service
error, that materially contributed to the current shared status mutation.
For determinism:
The controller-owned mapper in pkg/servicemanager is the only supported path
from normalized async class plus phase into shared OSOK conditions:
pending + create => Provisioning, requeuepending + update => Updating, requeuepending + delete => Terminating, requeuesucceeded + create|update => Active, no requeuesucceeded + delete => Terminating, keep requeueing until delete
confirmation clears the finalizer pathfailed, canceled, attention, and unknown => Failed, no requeue by
defaultResource runtimes may still own provider-specific raw-status normalization, but they must not invent separate condition mappings once they have a normalized class plus phase.
When a runtime has an explicit phase from the current OCI observation, that
phase wins over any previously persisted status.async.current.phase.
Persisted phase is only a fallback when the current observation cannot
determine phase directly.
When an opening OCI create, update, or delete response carries
OpcRequestId, the runtime should seed status.opcRequestId immediately,
before later follow-up observations drop the header. New controller-backed
resources should inherit this through generatedruntime by default, and any
future handwritten runtime must mirror the same shared field explicitly.
When an opening OCI create, update, or delete response carries
OpcWorkRequestId, the runtime should seed
status.async.current.workRequestId immediately, before later response
projection or lifecycle rereads drop the header.
That breadcrumb capture does not, by itself, promote a resource to
workrequest. Lifecycle resources may still continue on read-after-write,
lifecycle-state requeue, or confirm-delete follow-up behavior. Headerless
in-flight follow-up observations should preserve the already seeded
workRequestId until terminal completion or explicit tracker clear, just as
headerless follow-up observations preserve the last non-empty
status.opcRequestId.
shared.OSOKStatus.Async.Current is canonical immediately.
During the staged migration window:
queue/Queue keeps createWorkRequestId, updateWorkRequestId, and
deleteWorkRequestId for resume parity, but it must mirror the same
in-flight operation into the shared tracker.async.strategy to workrequest.events create;patch) through the shared default controller markers.generation.resources[].controller.extraRBACMarkers should record only
non-default access such as secret reads or writes, not event-recorder
boilerplate.