Files
cgalo5758 5b6cdd117b Specify system tenant for ownerless sites
Add the OpenSpec proposal, design, tasks, and requirements for an
app-ensured tenant resolved by natural key instead of configured UUIDs.

Align FedWiki, entitlement, and provider lifecycle specs around active
and non-active site states, and record related operator UX follow-ups.
2026-06-24 00:32:53 -05:00

4.2 KiB

provider-lifecycle-contract

Purpose

Defines the lifecycle contract every provisioning provider conforms to: the set of mutating and read operations a provider may declare support for, and the division of ownership whereby the console owns intent and aggregate facts while the provider owns canonical per-instance state.

Requirements

Requirement: A provider declares the lifecycle operations it supports

The lifecycle contract SHALL comprise the operations create, set_status, and delete, and a read class of list and describe. create provisions a new instance and delete permanently (irreversibly) removes one; set_status moves an existing instance between the lifecycle states the provider declares (see "A provider declaring set_status declares its lifecycle state set"). Each provider SHALL declare which operations it supports via provider_operations. An operator or system action for a given operation SHALL be offered only for providers that declare support for it. Every provisioning provider SHALL declare at least one read operation so its instances can be enumerated.

Scenario: Provider declares its supported verbs

  • WHEN a provisioning provider is registered
  • THEN provider_operations SHALL record the operations it supports from {create, set_status, delete, list, describe}
  • AND the set SHALL include at least one read operation (list or describe)

Scenario: Action gated on declaration

  • WHEN a provider does not declare set_status
  • THEN no status-change action (read-only, archive, restore) SHALL be offered for that provider

Requirement: The console owns intent; the provider owns canonical per-instance state

Canonical per-instance state SHALL live provider-side. The member-console SHALL own intent and aggregate facts — resource counts, limits, and requested operations. The console MAY maintain an observed projection of per-instance state (a cache refreshed from the provider's read class) for display, reconciliation, and provenance, provided the provider remains the canonical source of truth and the projection is never treated as authoritative over the provider.

Scenario: Console stores intent and an observed projection, provider stays canonical

  • WHEN a downgrade requests that an instance become read-only
  • THEN the console SHALL record the intent and the limit
  • AND the console MAY record an observed per-instance status as a projection
  • AND the provider SHALL remain the canonical source of truth for that status

Scenario: The observed projection is refreshed via the read class

  • WHEN the console reconciles per-instance state
  • THEN it SHALL refresh its observed projection from the provider's list/describe (the read class)
  • AND it SHALL NOT treat the projection as an independent source of truth that can diverge from the provider unreconciled

Requirement: set_status moves an instance between provider-declared states

The set_status operation SHALL move an instance to a target state drawn from the provider's declared state set. The active state SHALL be the implicit baseline that every provisioning provider supports. Non-active states (e.g. readonly, archived) SHALL be reversible — set_status SHALL be able to return an instance to active. set_status to a state the provider does not declare SHALL be refused. delete is terminal and distinct from the reversible state machine — it is not a set_status target.

Scenario: Transition to a declared state

  • WHEN set_status(readonly) is requested for an instance of a provider that declares the readonly state
  • THEN the provider SHALL move the instance to readonly

Scenario: Transition is reversible back to active

  • WHEN set_status(active) is requested for an instance currently readonly
  • THEN the provider SHALL return the instance to active

Scenario: Transition to an undeclared state is refused

  • WHEN set_status(suspended) is requested for a provider that does not declare a suspended state
  • THEN the request SHALL be refused

Scenario: Delete is not a status target

  • WHEN an instance is deleted
  • THEN removal SHALL occur via the terminal delete operation, not via set_status