v1alpha1

package
v0.7.1 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 5, 2026 License: Apache-2.0 Imports: 13 Imported by: 0

Documentation

Overview

Package v1alpha1 holds the v1alpha1 API types — shared between server, client, and SDK. It imports api/fault for validation errors and github.com/danielgtaylor/huma/v2 for the SchemaProvider methods that carry leaf constraints into the generated OpenAPI (ADR-0048). It remains a public-contract leaf: the ADR-0002 §7 depguard rule still holds — api/** imports nothing from internal/** / pkg/** (huma is a third-party SDK, allowed).

Index

Constants

View Source
const (
	MaxInvokeTimeout     = time.Hour
	DefaultInvokeTimeout = 60 * time.Second
)

The bounds of an external invoke's response deadline (ADR-0151): FunctionSpec.Timeout and invoke.defaultTimeout.

View Source
const (
	// DefaultMaxValueBytes is the default per-value cap (1 MiB) when KVStoreSpec.MaxValueBytes is 0.
	DefaultMaxValueBytes int64 = 1 << 20
	// MaxValueBytesLimit is the largest spec.maxValueBytes a store may declare: the worker-node local API
	// buffers a KV put body up to this size, so a larger cap could never be served.
	MaxValueBytesLimit int64 = 1 << 20
	// DefaultMaxKeyBytes is the default per-key cap (1 KiB) when KVStoreSpec.MaxKeyBytes is 0.
	DefaultMaxKeyBytes int = 1024
	// MaxKeyBytesLimit is the largest spec.maxKeyBytes a store may declare: the durable KV engine (Badger)
	// stores keys of at most 65000 bytes, and the stored key <ns>/<store>/<table>/<key> adds at most 192
	// bytes (three DNS labels and their slashes), so every key within this cap can be stored.
	MaxKeyBytesLimit int = 64000
)

Default per-op caps for a KVStore (ADR-0072): applied where the spec value is read when 0.

View Source
const (
	Group   = "funcd.io"
	Version = "v1alpha1"
)

Group and Version are the wire identity of every funcd resource.

View Source
const DNSLabel = `^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$`

DNSLabel is the RFC-1123 DNS-label pattern — the SINGLE source for both server-side validation (dnsLabel below) and the generated OpenAPI schema (the SchemaProvider methods), so the published contract can never drift from the admission check.

Variables

This section is empty.

Functions

func ControlledBy added in v0.4.0

func ControlledBy(refs []OwnerReference, kind Kind, uid UID) bool

ControlledBy reports whether refs' controller reference is the object of kind with uid.

func FieldDiffs

func FieldDiffs(d []FieldDiff) string

FieldDiffs renders field diffs into one deterministic message (sorted by field).

Types

type Action

type Action struct {
	Name     ObjectName      `json:"name"`
	On       ObjectName      `json:"on"`                 // the dependency (Dependency.Name) this fires on
	Workflow ObjectName      `json:"workflow,omitempty"` // start a WorkflowRun of this Workflow
	Function ObjectName      `json:"function,omitempty"` // invoke this Function with the CloudEvent
	Input    json.RawMessage `json:"input,omitempty"`    // object; literals or ${{ event.* }} (checked at reconcile)
}

Action is a named, kind-keyed reaction bound to one dependency (ADR-0109). Exactly one of Workflow/Function is set. Input (optional) is a JSON object whose values are literals or `${{ event.* }}` projections over the firing CloudEvent (the F73 engine); absent ⇒ the event data verbatim.

type AssignmentEntry

type AssignmentEntry struct {
	Principal *PrincipalRef `json:"principal,omitempty"`
	RoleRef   RoleRef       `json:"roleRef"`
	Scope     *ScopeRef     `json:"scope,omitempty"`
}

AssignmentEntry is one (principal, role, scope) grant. Principal/Scope inherit the RolesAssignment's top-level defaults when omitted.

type AuthMode

type AuthMode string

AuthMode selects whether the edge authenticates the caller for a target (ADR-0113, F77).

const (
	// AuthAuthenticated requires a valid bearer + a PDP allow.
	AuthAuthenticated AuthMode = "authenticated"
	// AuthOpen allows anonymous access (the zero/default stance, phased).
	AuthOpen AuthMode = "open"
)

func (AuthMode) Schema

func (AuthMode) Schema(huma.Registry) *huma.Schema

Schema renders the huma enum for AuthMode (empty accepted, normalizes to open).

type BlobEvent

type BlobEvent struct {
	Name   ObjectName      `json:"name"`
	Prefix string          `json:"prefix,omitempty"` // only objects under this key prefix fire ("" = whole bucket)
	On     []BlobEventType `json:"on,omitempty"`     // default [Created] (set in normalize); only Created supported in V1
}

BlobEvent is one named object-store event: a DNS-1123 name, a key prefix, and the object lifecycle events it fires on (ADR-0119).

type BlobEventType

type BlobEventType string

BlobEventType is an object lifecycle event. V1: Created only (Removed/Updated are a named follow-on).

const BlobCreated BlobEventType = "Created"

BlobCreated is the object-created lifecycle event — the only type supported in V1 (ADR-0119).

type BlobServiceSpec

type BlobServiceSpec struct {
	Binding string `json:"binding" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
}

BlobServiceSpec configures a blob service binding (ADR-0021, F23): the binding name a function references, the key-prefix segment <namespace>/<binding>/<key>.

type BlobSource

type BlobSource struct {
	Bucket ObjectName  `json:"bucket"` // the ADR-0080 Bucket resource to watch (this namespace)
	Events []BlobEvent `json:"events"` // ≥1; unique names
}

BlobSource hosts the blob kind's named events over one Bucket (ADR-0119, F83): a poll watcher lists the Bucket's prefixes and fires a named CloudEvent per new object.

type Bucket

type Bucket struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       BucketSpec `json:"spec"`
}

Bucket is a namespaced blob domain (ADR-0080): the S3 *bucket*, mirroring KVStore — a named domain with a set of sub-domains (prefixes, the medallion layers) each with a single-writer owner, and an optional per-object resource policy. A function reaches a prefix only through a Function.spec.blob binding (default-deny); the prefix's owner is the single writer. Unlike KVStore, Bucket carries NO observed status (no reconciler) — it is a pure data-model resource. Deletion-protected by referencing bindings and by non-empty data.

func (*Bucket) GroupVersionKind

func (b *Bucket) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Bucket.

func (*Bucket) Validate

func (b *Bucket) Validate() error

Validate performs envelope validation via the shared validateMeta helper, then the BucketSpec rules JSON Schema can't express: MaxObjectBytes is non-negative; and within the bucket, prefix names are unique (⇒ a prefix has exactly one owner) and each is a DNS-1123 label. Cross-resource rules (the owner exists) are an admission (ADR-0080), not structural Validate.

type BucketPrefix

type BucketPrefix struct {
	// Name is the key prefix; a DNS-1123 label, unique within the bucket. The medallion layer.
	Name string `json:"name" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
	// Owner is the single writer: a Function in this bucket's namespace. Empty ⇒ no writer (read-only).
	// Cross-resource validity (the owner exists) is an admission, not Validate.
	Owner ObjectName `json:"owner,omitempty"`
}

BucketPrefix is one sub-domain of a Bucket (ADR-0080): a named key prefix with a single-writer owner. Mirrors KVTable. The leading segment of an S3 key selects the prefix; the rest is the object path.

type BucketSpec

type BucketSpec struct {
	// Prefixes are the bucket's sub-domains (ADR-0080): the medallion layers, each a key prefix with a
	// single-writer Owner. Prefix names are unique within the bucket (so a prefix has exactly one owner
	// by construction). Empty ⇒ a bucket with no writable sub-domains.
	Prefixes []BucketPrefix `json:"prefixes"`
	// MaxObjectBytes is the per-object resource policy on THIS bucket (a write past it ⇒ PayloadTooLarge);
	// 0 ⇒ unset (no per-bucket cap; the daemon-wide s3gateway.maxUploadBytes still applies).
	MaxObjectBytes int64 `json:"maxObjectBytes,omitempty" minimum:"0"`
}

BucketSpec is the desired state of a Bucket (ADR-0080): its sub-domains (prefixes) and an optional per-object resource policy. Each prefix is a key-prefix sub-domain with a single-writer owner.

type BuiltinStep

type BuiltinStep struct {
	// Wait is a timer: a Go duration string ("30s") or a ${{ }} goja Select expression evaluating
	// to a number of seconds. The step blocks in-engine for the duration (on the run context, so the
	// run-timeout interrupts it), then passes its flowing input through as output. A normal step —
	// Running then Succeeded; no special state.
	Wait string `json:"wait,omitempty"`
	// Pass is a ${{ }} goja Select expression over the step's flowing input + prior step outputs;
	// its result is the step's output. No dispatch.
	Pass string `json:"pass,omitempty"`
}

BuiltinStep is an engine-native step (ADR-0096) — a nested kind-union of exactly one of Wait / Pass, evaluated in-process (no container, no dispatch). Room to grow (Gate, F66).

type CatalogIngress

type CatalogIngress struct {
	// PathPrefix is the edge path the proxy is exposed at, e.g. "/catalog/lake". Required (leading "/").
	PathPrefix string `json:"pathPrefix"`
	// Host is an optional exact host match ("" = any host), mirroring gateway.Route.Host (V1).
	Host string `json:"host,omitempty"`
}

CatalogIngress declares external edge exposure of a CatalogService's catalog::query PEP proxy (ADR-0138). huma derives the schema from these tags (no hand-written Schema(), like CatalogRef).

type CatalogRef

type CatalogRef struct {
	// Bucket is the name of a Bucket in this service's namespace.
	Bucket ObjectName `json:"bucket"`
	// Prefix is a sub-domain (BucketPrefix.name) of that bucket; a DNS-1123 label. The SQLite catalog
	// lives at <prefix>/_ducklake/catalog.db.
	Prefix string `json:"prefix" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
}

CatalogRef names the bound (bucket, prefix) the DuckLake catalog syncs under (ADR-0086). The prefix must be OWNED by this service's function (single-writer); the SQLite catalog file lives at <prefix>/_ducklake/catalog.db. Cross-resource validity (the bucket/prefix exist, owner is this service's function) is the catalog-blob-validity admission's job, NOT Validate.

type CatalogService

type CatalogService struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       CatalogServiceSpec   `json:"spec"`
	Status     CatalogServiceStatus `json:"status,omitempty"`
}

CatalogService is a namespaced add-on-provider instance (ADR-0086, F48): a governed SQL catalog + query engine (DuckLake + DuckDB + Quack) over the Parquet a tenant already stores on funcd's blob. Modeled on KVStore — a status-bearing namespaced resource whose reconciler materializes a backing min-replica=1 `duckdb` Function (the declared spec.blob bindings, so ADR-0085 injects the per-fn S3 keypair). The engine is the deployed Function, exposed through the EXISTING function→gateway path (ADR-0013) — there is NO Route resource. DuckDB reads/writes Parquet only through the F47 S3 surface under binding-as-grant; its DuckLake catalog lives on the same blob (a reserved `_ducklake/catalog.db` key in an owned prefix), loaded + checkpointed by the single replica. cgo never touches the daemon — DuckDB runs out-of-process in the curated image.

func (*CatalogService) GetStatus

func (c *CatalogService) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject (the controller's write-back seam).

func (*CatalogService) GroupVersionKind

func (c *CatalogService) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for CatalogService.

func (*CatalogService) Validate

func (c *CatalogService) Validate() error

Validate performs envelope validation via the shared validateMeta helper, then the CatalogServiceSpec rules JSON Schema can't express (mirrors KVStore.Validate / FunctionSpec.Validate's blob loop): each spec.blob entry's alias + prefix is a DNS-1123 label and the alias is unique within Blob; Catalog.Prefix is a DNS-1123 label; and the catalog (bucket, prefix) is one of the spec.blob bindings (so the engine gets the per-fn S3 keypair and can write its own catalog — ADR-0086). Cross- resource validity (the bucket/prefix actually EXIST in the namespace) is the catalog-blob-validity admission, NOT structural Validate.

type CatalogServiceSpec

type CatalogServiceSpec struct {
	// Blob binds the lakehouse buckets the engine may read/write — the SAME shape as
	// Function.spec.blob (ADR-0080), projected onto the backing Function so ADR-0085 injects the
	// per-fn keypair. The prefix the catalog lives under must be OWNED by this service's function
	// (single-writer).
	Blob []FunctionBlob `json:"blob"`
	// Catalog names the bound (bucket, prefix) the DuckLake catalog syncs under (a `_ducklake/` key);
	// the prefix must be OWNED by this service's function (single-writer). The SQLite catalog file
	// lives at <prefix>/_ducklake/catalog.db.
	Catalog CatalogRef `json:"catalog"`
	// Resources sizes the engine (cpu/mem); DuckDB is memory-hungry. The provider-runtime maps it
	// onto runtime.Limits when numerically parseable (ADR-0087), else it is recorded forward-compat.
	Resources ResourceSpec `json:"resources,omitempty"`
	// Secrets names the Secret resources in this namespace whose Data is injected into the engine
	// as env vars (ADR-0087, reusing the ADR-0057 FunctionSpec.Secrets convention verbatim): the
	// Quack token (QUACK_TOKEN). Each named Secret's Data keys become engine env-var names;
	// reserved FUNCD_* keys are never overridable. Only the NAMES are persisted; resolved values
	// live only in the engine's env. Resolution is PDP-authorized (ADR-0022/0057); an unauthorized
	// or missing Secret fails the service closed (not Ready). Empty ⇒ no secret injection.
	Secrets []ObjectName `json:"secrets,omitempty"`
	// Config names the ConfigMap resources in this namespace whose Data is injected into the engine
	// as env vars (ADR-0087): engine tuning (DUCKDB_*). Same env-injection shape as Secrets, but
	// from non-sensitive ConfigMap Data. Empty ⇒ no config injection.
	Config []ObjectName `json:"config,omitempty"`
	// Ingress declares OPT-IN external edge exposure of this catalog's catalog::query PEP proxy
	// (ADR-0138). Nil ⇒ internal-only (no edge route — today's default). Set ⇒ once Ready, the
	// reconciler programs an ingress route to the PEP PROXY (never the engine), so an external caller
	// is PEP'd on catalog::query exactly like an internal one. Exposure is a network path, not a grant:
	// default-deny is preserved (an external Identity still needs a RolesAssignment).
	Ingress *CatalogIngress `json:"ingress,omitempty"`
}

CatalogServiceSpec is the desired state of a CatalogService (ADR-0086): the lakehouse blob bindings the engine may read/write, the (bucket, prefix) the DuckLake catalog syncs under, and the engine's recorded resource sizing.

type CatalogServiceStatus

type CatalogServiceStatus struct {
	Status `json:",inline"`
	// Function is the materialized backing duckdb Function (computed by the reconciler).
	Function ObjectName `json:"function,omitempty"`
	// Endpoint is the published Quack URL — the backing function's ingress path (computed).
	Endpoint string `json:"endpoint,omitempty"`
	// ProxyPort is the port of the catalog's PEP proxy listener (ADR-0162), recorded so a restarted daemon binds the
	// same port again and the URL consumers hold keeps reaching this catalog (computed).
	ProxyPort int `json:"proxyPort,omitempty"`
}

CatalogServiceStatus is the observed state of a CatalogService (ADR-0086): the reconciler reflects readiness (Ready once the backing duckdb Function is up), the materialized backing Function, and the published Quack endpoint. It embeds the shared Status (Phase + Conditions) so the controller's generic write-back seam (StatusObject.GetStatus) points at the live status — there is NO separate /status route.

type Condition

type Condition struct {
	Type               ConditionType   `json:"type"`
	Status             ConditionStatus `json:"status"`
	ObservedGeneration int64           `json:"observedGeneration,omitempty"`
	LastTransitionTime time.Time       `json:"lastTransitionTime,omitempty"`
	Reason             string          `json:"reason,omitempty"`
	Message            string          `json:"message,omitempty"`
}

Condition represents a single observed condition on a resource's status.

type ConditionStatus

type ConditionStatus string

ConditionStatus is the state of a condition: True, False, or Unknown.

const (
	ConditionTrue    ConditionStatus = "True"
	ConditionFalse   ConditionStatus = "False"
	ConditionUnknown ConditionStatus = "Unknown"
)

type ConditionType

type ConditionType string

ConditionType is an open string type identifying a condition. Well-known types (Ready, Scheduled, RouteConfigured, …) are defined by the feature ADRs that raise them.

type Conditions

type Conditions []Condition

Conditions is an ordered set of conditions.

func (Conditions) Get

func (cs Conditions) Get(t ConditionType) (Condition, bool)

Get returns the condition with the given Type, and whether it was found.

func (*Conditions) Set

func (cs *Conditions) Set(c Condition)

Set upserts a condition by Type. If a condition of the same Type already exists, it is replaced in place. LastTransitionTime is advanced only when the Status actually changes — the status-bookkeeping contract every controller relies on.

type ConfigMap

type ConfigMap struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       ConfigMapSpec `json:"spec"`
}

ConfigMap is a namespaced, pure-data resource for non-sensitive configuration key/values. ConfigMap does NOT have status — it implements Object, not StatusObject.

func (*ConfigMap) GroupVersionKind

func (c *ConfigMap) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for ConfigMap.

func (*ConfigMap) Validate

func (c *ConfigMap) Validate() error

Validate performs envelope validation, then requires every data key to be an env-var name.

type ConfigMapSpec

type ConfigMapSpec struct {
	Data map[string]string `json:"data,omitempty"`
}

ConfigMapSpec holds the configuration data. map[string]string is allowed under ADR-0002 (the any-ban targets interface{}/any/map[string]any).

type DeletionPolicy

type DeletionPolicy string

DeletionPolicy is a workflow-owned store's delete behavior.

const (
	// DeletionRetain leaves the store on workflow delete (the default).
	DeletionRetain DeletionPolicy = "retain"
	// DeletionDelete cascades the store on workflow delete.
	DeletionDelete DeletionPolicy = "delete"
)

func (DeletionPolicy) Schema

Schema carries DeletionPolicy's enum into the generated OpenAPI (ADR-0048).

type Dependency

type Dependency struct {
	Name   ObjectName `json:"name"`
	Source ObjectName `json:"source"` // the EventSource name
	Event  ObjectName `json:"event"`  // the named event of that source
}

Dependency is a named, tuple-addressed event dependency: (source, event) in this namespace.

type EdgeAuth

type EdgeAuth struct {
	Mode AuthMode `json:"mode,omitempty"`
}

EdgeAuth is the F77 namespace-default auth stance.

type EdgeDefaults

type EdgeDefaults struct {
	// Auth is the namespace-default edge auth stance (ADR-0113, F77); a Route overrides it. nil ⇒
	// open (the phased default — a namespace opts into default-deny by setting Auth.Mode=authenticated).
	Auth *EdgeAuth `json:"auth,omitempty"`
}

EdgeDefaults carries namespace-wide edge policy defaults (F74–F78 add typed sub-structs).

type EgressPolicy

type EgressPolicy struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       EgressPolicySpec `json:"spec"`
}

EgressPolicy is a namespaced, pure-policy allow-list (implicit default-deny) governing worker egress (ADR-0117, F81). No status (implements Object, not StatusObject). A namespace with no EgressPolicy ⇒ its workers reach nothing external. It is the first high-level typed policy CRD that compiles to Cedar (internal/auth/cedar.CompileEgressPolicy). Example (YAML block syntax):

apiVersion: funcd.io/v1alpha1
kind: EgressPolicy
metadata:
  name: default-egress
  namespace: acme
  resourceGroup: rg1
spec:
  appliesTo: [etl]        # optional; omit ⇒ every Function in the namespace
  rules:
    - to:
        domains: ["api.x.com", "*.x.com"]
        cidrs:   ["10.0.0.0/8"]
      ports: [443, 5432]

func (*EgressPolicy) GroupVersionKind

func (ep *EgressPolicy) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for EgressPolicy.

func (*EgressPolicy) Validate

func (ep *EgressPolicy) Validate() error

Validate performs envelope validation then the allow-list rules: at least one rule; each rule has a non-empty `to` (≥1 domain or CIDR); domains are DNS names or "*."-prefixed wildcards; CIDRs parse (netip.ParsePrefix); ports are 1..65535 (fault.Invalid otherwise).

type EgressPolicySpec

type EgressPolicySpec struct {
	// Rules is the allow-list; each grants egress to its `to` on its `ports`. At least one required.
	Rules []EgressRule `json:"rules"`
	// AppliesTo scopes every rule to these Functions (by name, this namespace); empty ⇒ the whole namespace.
	AppliesTo []ObjectName `json:"appliesTo,omitempty"`
}

EgressPolicySpec is an allow-list of egress rules, optionally scoped to named Functions.

type EgressRule

type EgressRule struct {
	// To is the destination match; at least one of domains/cidrs is required (Validate enforces).
	To EgressTo `json:"to"`
	// Ports are the destination ports (1..65535); empty ⇒ any port to the matched destination.
	Ports []int `json:"ports,omitempty"`
}

EgressRule permits egress to a destination set on a port set.

type EgressTo

type EgressTo struct {
	Domains []string `json:"domains,omitempty"`
	CIDRs   []string `json:"cidrs,omitempty"`
}

EgressTo is a destination match: SNI/Host domains (wildcard "*.x.com" ok) and/or CIDRs.

type EventSource

type EventSource struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       EventSourceSpec   `json:"spec"`
	Status     EventSourceStatus `json:"status,omitempty"`
}

EventSource is a namespaced resource that configures an event trigger source. Status-bearing. Behavioral spec fields (source config) owned by F16.

func (*EventSource) GetStatus

func (es *EventSource) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*EventSource) GroupVersionKind

func (es *EventSource) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for EventSource.

func (*EventSource) Normalize

func (es *EventSource) Normalize()

Normalize fills declared-but-empty defaults that JSON Schema cannot (ADR-0119): each blob event's empty `on` defaults to [Created]. It is a decode/normalize step — pure defaulting, NOT validation — kept out of Validate so Validate stays non-mutating (ADR-0108). Idempotent; a nil/timer spec is a no-op.

func (*EventSource) Validate

func (es *EventSource) Validate() error

Validate enforces the v2 kind-union rules JSON Schema can't express (ADR-0108/ADR-0048): exactly one source kind set; each kind's events non-empty with unique DNS-1123 names and in-bounds intervals. The removed v1 `type:`/`function:` keys are rejected at the schema edge (additionalProperties:false → 422).

type EventSourceSpec

type EventSourceSpec struct {
	// Timer is the timer source kind (V1): named events, each ticking on its own interval. The webhook
	// source kind is a named follow-on (it needs an eventing-ingress gateway decision).
	Timer *TimerSource `json:"timer,omitempty"`
	// Blob is the object-store source kind (ADR-0119, F83): named events that fire on object-created under
	// a watched Bucket prefix, detected by a poll watcher over the ADR-0007 blob.Bucket List seam.
	Blob *BlobSource `json:"blob,omitempty"`
}

EventSourceSpec is a kind-keyed source hosting named events (ADR-0108, F72): exactly one source-kind pointer is non-nil (the source kind), each carrying a list of named events. A firing publishes a named CloudEvent that the F69 Sensor (ADR-0109) binds to actions — the source no longer binds a function.

type EventSourceStatus

type EventSourceStatus struct {
	Status `json:",inline"`
}

EventSourceStatus holds the observed state.

type ExposureMode

type ExposureMode string

ExposureMode selects whether an unrouted Function is reachable at the public edge.

const (
	// ExposureImplicit keeps the /function/<name> path reachable (default, back-compat).
	ExposureImplicit ExposureMode = "implicit"
	// ExposureExplicit gates the edge: no Route ⇒ private (default-deny ingress).
	ExposureExplicit ExposureMode = "explicit"
)

func (ExposureMode) Normalized

func (m ExposureMode) Normalized() ExposureMode

Normalized returns the effective mode, mapping the empty/absent zero value to implicit.

func (ExposureMode) Schema

Schema renders the huma enum for ExposureMode (empty accepted, normalizes to implicit).

type FieldDiff

type FieldDiff struct {
	Field string
	Want  string
	Got   string
}

FieldDiff is one required consumer field a producer or document does not satisfy. Got == "" ⇒ the field is missing; otherwise Got is the actual primitive type and Want the required one. Field == "" ⇒ the whole document is mistyped (a non-null document against a void schema).

func CheckInput

func CheckInput(doc, schema json.RawMessage) []FieldDiff

CheckInput reports the required properties of the schema not satisfied by an actual JSON document (doc↔schema primitive match). A JSON number satisfies integer or number (a doc can't distinguish them). A void schema admits only a null or absent document (ADR-0090). Empty ⇒ valid. Used by WorkflowRun admission and the engine's run-start gate (ADR-0098).

func CheckProps added in v0.3.0

func CheckProps(doc, schema json.RawMessage) []FieldDiff

CheckProps reports the top-level fields of a JSON document whose primitive type does not match the type the schema declares for that property; an undeclared field is not checked. Unlike CheckInput it checks what the document carries, not what the schema requires: a step's spec.params overlay only part of its input (ADR-0094). A non-object document against an object schema is one whole-document diff.

func (FieldDiff) String

func (d FieldDiff) String() string

type Function

type Function struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       FunctionSpec   `json:"spec"`
	Status     FunctionStatus `json:"status,omitempty"`
}

Function is a namespaced resource representing a deployable function/agent. Status-bearing. Behavioral spec fields owned by F10–F14.

NOTE: `json:",inline"` flattens TypeMeta because stdlib encoding/json treats an empty tag name as "anonymous → promote fields" (the `inline` option itself is a no-op in stdlib; it's a yaml/k8s-codec convention). ObjectMeta keeps the name "metadata", so it nests. The roundtrip test guards this — do not rename the TypeMeta tag.

func (*Function) GetStatus

func (f *Function) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*Function) GroupVersionKind

func (f *Function) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Function.

func (*Function) Validate

func (f *Function) Validate() error

Validate performs envelope validation via the shared validateMeta helper, then the Function-spec semantic rules JSON Schema can't express (ADR-0046, ADR-0048): Pooling.Worker is a DNS-1123 label when set; the cross-field and conditional-presence checks in FunctionSpec.Validate. Field-local constraints (runtime/handler/uri patterns, replica bounds) are schema-enforced at the edge and are not re-checked here.

type FunctionBlob

type FunctionBlob struct {
	// Alias is the local handle; a DNS-1123 label, unique within Blob.
	Alias string `json:"alias" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
	// Bucket is the name of a Bucket in this function's namespace.
	Bucket ObjectName `json:"bucket"`
	// Prefix is a sub-domain (BucketPrefix.name) of that bucket; a DNS-1123 label.
	Prefix string `json:"prefix" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
}

FunctionBlob declares one blob (S3) binding (ADR-0080, F47): a local alias bound to a (bucket, prefix) sub-domain in the same namespace. The binding is the read grant; writes require this function to be the prefix's owner. Mirrors FunctionKV (the wrangler/spec.kv convention).

type FunctionCatalog

type FunctionCatalog struct {
	// Alias names the FUNCD_CATALOG_<ALIAS>_* env pair; a DNS-1123 label, unique within Catalogs.
	Alias string `json:"alias" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
	// Catalog is the name of a CatalogService in this function's namespace.
	Catalog ObjectName `json:"catalog"`
}

FunctionCatalog binds this function to a CatalogService it consumes (ADR-0091, F61). Declaring the binding is the grant: funcd injects FUNCD_CATALOG_<ALIAS>_URL/_TOKEN, and (V2) grants egress.

type FunctionKV

type FunctionKV struct {
	// Alias is the local handle the handler passes to context.kv; a DNS-1123 label, unique within KV.
	Alias string `json:"alias" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
	// Store is the name of a KVStore in this function's namespace.
	Store ObjectName `json:"store"`
	// Table is a sub-domain (KVStore.spec.tables[].name) of that store; a DNS-1123 label.
	Table string `json:"table" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
}

FunctionKV declares one KV binding (ADR-0073, F42): a local alias bound to a (store, table) sub-domain in the same namespace. The handler reaches it as context.kv.<verb>(alias, …); reads are coarse-allowed for any bound same-namespace caller, writes require this function to be the table's owner. Mirrors FunctionLink (the wrangler/spec.links convention).

type FunctionLink struct {
	// Alias is the local name the handler passes to invoke; a DNS-1123 label, unique within Links.
	Alias string `json:"alias" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
	// Target is the name of a Function in this function's namespace.
	Target ObjectName `json:"target"`
	// Timeout bounds the synchronous wait (incl. a cold-start wake); int64 ns, 0 ⇒ platform
	// default, ≤5m.
	Timeout time.Duration `json:"timeout,omitempty" minimum:"0" maximum:"300000000000"`
}

FunctionLink declares one synchronous RPC dependency: a local alias bound to a target Function in the same namespace (ADR-0064, F33). The latest-Ready revision of the target is called.

type FunctionName

type FunctionName string

FunctionName is a DNS-label-qualified function identifier.

func (FunctionName) Schema

Schema carries FunctionName's DNS-1123 constraint into the generated OpenAPI.

func (FunctionName) Validate

func (n FunctionName) Validate() error

Validate checks the FunctionName against DNS-label rules.

type FunctionSpec

type FunctionSpec struct {
	// Scaling configures scale-to-zero / idle reclaim (ADR-0016, F11). V1 honors
	// MinReplicas (0 enables scale-to-zero) and IdleTimeout (0 disables reclaim);
	// MaxReplicas is recorded for forward-compatibility (1→N autoscaling is V3).
	Scaling Scaling `json:"scaling,omitempty"`
	// Runtime is the runtime class / language image (e.g. "nodejs22", "python312") — F13/ADR-0020.
	// Typed RuntimeName so its DNS-1123 constraint reaches the OpenAPI schema (ADR-0048).
	Runtime RuntimeName `json:"runtime,omitempty"`
	// Handler is the entrypoint the shim resolves at materialization (e.g. "app.handler") — F13.
	Handler string `json:"handler,omitempty" pattern:"^[A-Za-z_][A-Za-z0-9_.]*$"`
	// Image is the source artifact OCI ref (oci-layout:// · file:// · a bare registry ref; the tag at the
	// string end), pulled + served by the runtime — F13/ADR-0020, flattened by ADR-0097 (was spec.artifact.uri).
	Image string `json:"image,omitempty"`
	// ImageDigest is the content digest pinned into the stamped Revision ("what was validated ships"),
	// system-set at materialization (ADR-0035) — ADR-0097 (was spec.artifact.digest).
	ImageDigest string `json:"imageDigest,omitempty" pattern:"^sha256:[a-f0-9]{64}$"`
	// Replicas is the manual replica count (>=0); the effective count also honors Scaling + the
	// activator's wake (ADR-0016/0020) — F13.
	Replicas int `json:"replicas,omitempty" minimum:"0" maximum:"15"`
	// Timeout bounds an external invoke until its response starts; 0 ⇒ invoke.defaultTimeout. External
	// invokes only: links and steps keep their own limits (ADR-0151).
	Timeout time.Duration `json:"timeout,omitempty" minimum:"0" maximum:"3600000000000"`
	// Pooling is the per-function worker-pooling opt-in (ADR-0046, F28). Empty ⇒ solo (own
	// worker, the default). Functions sharing (namespace, runtime, Pooling.Worker) and the same
	// access (bindings, owned data, grants) co-locate as handlers in one pool worker; status.pool
	// names it.
	Pooling Pooling `json:"pooling,omitempty"`
	// Secrets names the Secret resources in this function's namespace whose Data is injected
	// into the worker as env vars at materialization (ADR-0057, F15 last mile). Each named
	// Secret's Data keys become env-var names; reserved FUNCD_* keys are never overridable.
	// Empty ⇒ no secret injection. Only the NAMES are persisted; resolved values are never
	// stored on the Function (they live only in the worker's env). Resolution is PDP-authorized
	// (ADR-0022/0018); an unauthorized or missing Secret fails the function closed (not Ready).
	Secrets []ObjectName `json:"secrets,omitempty"`
	// Config names the ConfigMap resources in this function's namespace whose Data is injected
	// into the worker as env vars at materialization (ADR-0093), mirroring Secrets but for
	// NON-sensitive config (a plain store read, no PDP). Config is merged BEFORE Secrets, so a
	// bound Secret overrides a config default. Reserved FUNCD_* keys are never overridable.
	// Empty ⇒ no config injection. Fails closed (not Ready, ConfigResolveFailed) if a named
	// ConfigMap is missing.
	Config []ObjectName `json:"config,omitempty"`
	// Links declares synchronous fn-to-fn RPC dependencies (ADR-0064, F33): each binds a local
	// alias to a target Function in this namespace, callable from the handler as
	// context.invoke(alias, input). The alias is the capability — with no matching link, invoke
	// fails closed. Empty ⇒ no links. Cross-resource validity (target exists, acyclic) is an
	// admission (ADR-0063); only the structural rules are checked in Validate.
	Links []FunctionLink `json:"links,omitempty"`
	// KV declares this function's KV bindings (ADR-0073, F42): each binds a local alias to a (store,
	// table) sub-domain in this namespace, reachable from the handler as context.kv.<verb>(alias, …).
	// The binding IS the capability — with no matching entry, context.kv on that alias is Forbidden
	// (default-deny). Mirrors spec.links (wrangler-style: naming lives on the consumer). Empty ⇒ no
	// KV access. Cross-resource validity (the store/table exist) is an admission (ADR-0063); only the
	// structural rules (alias is a unique DNS-1123 label) are checked in Validate.
	KV []FunctionKV `json:"kv,omitempty"`
	// Blob declares this function's blob (S3) bindings (ADR-0080, F47): each binds a local alias to a
	// (bucket, prefix) sub-domain in this namespace, reachable from the handler / its DuckDB as
	// s3://<bucket>/<prefix>/…. The binding IS the read capability — with no matching entry, blob access
	// on that alias is Forbidden (default-deny); writes require this function to be the prefix's owner.
	// Mirrors spec.kv (wrangler-style: naming lives on the consumer). Empty ⇒ no blob access.
	// Cross-resource validity (the bucket/prefix exist) is an admission; only the structural rules
	// (alias is a unique DNS-1123 label) are checked in Validate.
	Blob []FunctionBlob `json:"blob,omitempty"`
	// Catalogs declares this function's CatalogService consumer bindings (ADR-0091, F61): each binds a
	// local alias to a CatalogService in this namespace, injected into the worker as
	// FUNCD_CATALOG_<ALIAS>_URL (the catalog's status.endpoint) + FUNCD_CATALOG_<ALIAS>_TOKEN (its
	// QUACK_TOKEN). Declaring the binding IS the grant — only a declaring function receives the token;
	// it is never surfaced in CatalogService.status. The reconcile requeues (fail-closed) until the
	// bound catalog is Ready. Empty ⇒ no catalog consumption. Cross-resource validity (the catalog
	// exists) is an admission; only the structural rules (alias is a unique DNS-1123 label) are Validate.
	Catalogs []FunctionCatalog `json:"catalogs,omitempty"`
}

FunctionSpec holds the desired state. Behavioral fields are appended by feature ADRs:

runtime               → F12 (runtime port)
handler/artifact/shape → F13 (function contract & lifecycle)
scaling                → F11 (scale-to-zero)  [this field, ADR-0016]
triggers               → F10/F16 (routes / eventing)
services               → F14 (KV) and the service pattern

func (*FunctionSpec) Validate

func (s *FunctionSpec) Validate() error

Validate enforces the FunctionSpec rule JSON Schema can't express (ADR-0048): the Scaling cross-field bound (minReplicas ≤ maxReplicas when maxReplicas > 0). It deliberately does NOT re-check field PRESENCE (runtime/handler/artifact non-empty) — that is the materialization shape gate's job (ADR-0020: NewBasicValidator + the shim write ShapeValid:False and block Ready), and re-checking it here would duplicate a layer (one constraint, one layer). Field FORMAT (handler/digest patterns, replica/duration bounds) is schema-enforced at the edge.

type FunctionStatus

type FunctionStatus struct {
	Status          `json:",inline"`
	Replicas        int    `json:"replicas,omitempty"`        // workers that listened and get calls (ADR-0161)
	CurrentRevision string `json:"currentRevision,omitempty"` // the latest stamped Revision name (ADR-0020)
	// ServingRevision is the Revision whose workers receive the calls (ADR-0143); empty until the first deploy serves,
	// and again once no replica is desired.
	ServingRevision string `json:"servingRevision,omitempty"`
	// DrainingRevision is the Revision demoted at the last switch while any of its workers remain, and DrainingSince
	// the time of that switch (ADR-0143); both are cleared together.
	DrainingRevision string     `json:"drainingRevision,omitempty"`
	DrainingSince    *time.Time `json:"drainingSince,omitempty"`
	// Pool is the pool worker a pooled Function runs in, "<runtime>/<worker>/<access>"; empty when solo.
	Pool string `json:"pool,omitempty"`
}

FunctionStatus holds the observed state. Behavioral fields appended by F11/F13.

type FunctionStep

type FunctionStep struct {
	// Image is a full OCI artifact reference the workflow owns and materializes into a Function.
	Image string `json:"image,omitempty"`
	// Ref references an existing Function in the namespace (a shared service).
	Ref ObjectName `json:"ref,omitempty"`
	// Retry is the per-step retry policy; nil ⇒ the engine default.
	Retry *StepRetry `json:"retry,omitempty"`
	// Timeout is the per-step invocation bound; 0 ⇒ the engine default.
	Timeout time.Duration `json:"timeout,omitempty" minimum:"0" maximum:"86400000000000"`
	// Pooling overrides the workflow-level pooling for this step's materialized Function
	// (nil ⇒ inherit spec.pooling); image steps only.
	Pooling *WorkflowPooling `json:"pooling,omitempty"`
	// KV/Blob/Secrets/Config/Catalogs are the step's bindings (Function.spec shapes).
	KV       []FunctionKV      `json:"kv,omitempty"`
	Blob     []FunctionBlob    `json:"blob,omitempty"`
	Secrets  []ObjectName      `json:"secrets,omitempty"`
	Config   []ObjectName      `json:"config,omitempty"`
	Catalogs []FunctionCatalog `json:"catalogs,omitempty"`
}

FunctionStep is a dispatched step (ADR-0096): sourced from an OWNED Image (materialized into <workflow>-<step>) OR a Ref to an existing Function (exactly one). All dispatch-only knobs live here, so an engine-native (Builtin) step cannot express them by construction.

type Gateway

type Gateway struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Status     GatewayStatus `json:"status,omitempty"`
}

Gateway is a cluster-scoped resource representing the API gateway / ingress controller. Status-bearing. Behavioral fields (listeners, TLS) owned by F10.

func (*Gateway) GetStatus

func (gw *Gateway) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*Gateway) GroupVersionKind

func (gw *Gateway) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Gateway.

func (*Gateway) Validate

func (gw *Gateway) Validate() error

Validate performs envelope validation via the shared validateMeta helper.

type GatewayStatus

type GatewayStatus struct {
	Status `json:",inline"`
}

GatewayStatus holds the observed state.

type Grant

type Grant struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       GrantSpec `json:"spec"`
}

Grant is a namespaced, pure-policy resource (KindGrant stays registered). ADR-0072 made it a KV binding ({function, binding, store, mode}); ADR-0073 supersedes that — KV bindings moved to Function.spec.kv and authorization to the PDP/IAM — so GrantSpec reverts to its reserved empty placeholder. KindGrant remains registered (CRUD plumbing intact) for a future IAM ADR to fill; nothing in KV references Grant anymore. Grant has no status — it implements Object, not StatusObject.

func (*Grant) GroupVersionKind

func (g *Grant) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Grant.

func (*Grant) Validate

func (g *Grant) Validate() error

Validate performs envelope validation via the shared validateMeta helper. The empty GrantSpec has no structural rules of its own (reserved placeholder — ADR-0073).

type GrantSpec

type GrantSpec struct{}

GrantSpec is the reserved IAM-V2 placeholder (ADR-0073): empty until a future IAM ADR defines it.

type GroupVersionKind

type GroupVersionKind struct {
	Group   string
	Version string
	Kind    Kind
}

GroupVersionKind is the (Group, Version, Kind) triple used for registry lookup, ObjectRef identity, and codegen.

func (GroupVersionKind) APIVersion

func (gvk GroupVersionKind) APIVersion() string

APIVersion returns the wire apiVersion string, e.g. "funcd.io/v1alpha1".

func (GroupVersionKind) String

func (gvk GroupVersionKind) String() string

String returns a human-readable representation.

type HTTPMethod

type HTTPMethod string

HTTPMethod is an allowed request method.

const (
	MethodGet     HTTPMethod = "GET"
	MethodHead    HTTPMethod = "HEAD"
	MethodPost    HTTPMethod = "POST"
	MethodPut     HTTPMethod = "PUT"
	MethodPatch   HTTPMethod = "PATCH"
	MethodDelete  HTTPMethod = "DELETE"
	MethodOptions HTTPMethod = "OPTIONS"
)

func (HTTPMethod) Schema

func (HTTPMethod) Schema(huma.Registry) *huma.Schema

Schema renders the huma enum for HTTPMethod.

type Identity

type Identity struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       IdentitySpec   `json:"spec"`
	Status     IdentityStatus `json:"status,omitempty"`
}

Identity is a user-assigned managed identity (ADR-0135, FEAT-0008/F100): a first-class, namespace-scoped principal for a non-funcd caller. Its controller issues a revocable SigV4 keypair into an owned Secret and registers it so the caller resolves (via the S3 gateway's principalFor) to Identity::"<ns>/<name>". Issuing a credential is AUTHENTICATION only — authorization is granted separately (ADR-0136 RolesAssignment); an Identity with no assignment is default-deny.

func (*Identity) GetStatus

func (i *Identity) GetStatus() *Status

GetStatus returns the shared status base (Identity is a StatusObject — its reconciler reports credential issuance).

func (*Identity) GroupVersionKind

func (i *Identity) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Identity.

func (*Identity) Validate

func (i *Identity) Validate() error

Validate performs envelope + structural validation. Cross-resource checks (e.g. Secret existence) are reconcile-time, not here (ADR-0121).

type IdentitySpec

type IdentitySpec struct {
	// Type is the identity flavor. V1: only "external". Required.
	Type IdentityType `json:"type" enum:"external"`
	// CredentialSecretName is the owned Secret the issued keypair is written to. Empty ⇒ the Identity's
	// own name.
	CredentialSecretName ObjectName `json:"credentialSecretName,omitempty"`
	// Rotate, when incremented past status.observedRotate, forces the controller to reissue the secret
	// (rotation). The access key id is stable; only the secret changes.
	Rotate int64 `json:"rotate,omitempty"`
}

IdentitySpec declares a managed identity and how its credential is issued.

type IdentityStatus

type IdentityStatus struct {
	Status `json:",inline"`
	// AccessKeyID is the issued, stable SigV4 access key id (the secret lives only in the owned Secret).
	AccessKeyID string `json:"accessKeyId,omitempty"`
	// ObservedRotate mirrors the spec.rotate the currently-issued secret corresponds to.
	ObservedRotate int64 `json:"observedRotate,omitempty"`
}

IdentityStatus is the observed credential state.

type IdentityType

type IdentityType string

IdentityType is the flavor of a managed Identity. V1 supports only "external" — a non-funcd caller that authenticates with an issued SigV4 keypair. A Function's identity is system-assigned (implicit) and is not modeled as an Identity resource.

const IdentityTypeExternal IdentityType = "external"

IdentityTypeExternal is a user-assigned managed identity for a non-funcd (external) caller.

type Invocation

type Invocation struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Status     InvocationStatus `json:"status,omitempty"`
}

Invocation is a namespaced, read-only resource representing a single function invocation record. Status-bearing.

func (*Invocation) GetStatus

func (inv *Invocation) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*Invocation) GroupVersionKind

func (inv *Invocation) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Invocation.

func (*Invocation) Validate

func (inv *Invocation) Validate() error

Validate performs envelope validation via the shared validateMeta helper. Note: Invocation is namespaced (KindInvocation.Namespaced() is true).

type InvocationStatus

type InvocationStatus struct {
	Status    `json:",inline"`
	StartTime time.Time `json:"startTime,omitempty"`
	EndTime   time.Time `json:"endTime,omitempty"`
	Error     string    `json:"error,omitempty"`
}

InvocationStatus holds the observed invocation record. Behavioral fields (retention policy) owned by F16.

type JoinMode

type JoinMode string

JoinMode is a step's fan-in mode.

const (
	// JoinAll requires every parent to have Succeeded (the default).
	JoinAll JoinMode = "all"
	// JoinAny requires at least one parent to have Succeeded (exclusive-branch merge).
	JoinAny JoinMode = "any"
)

func (JoinMode) Schema

func (JoinMode) Schema(huma.Registry) *huma.Schema

Schema carries JoinMode's enum into the generated OpenAPI (ADR-0048).

type KVServiceSpec

type KVServiceSpec struct {
	Binding string `json:"binding" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
}

KVServiceSpec configures a KV service binding (ADR-0019, F14): the binding name a function references, which becomes the key-prefix segment <namespace>/<binding>/<key>.

type KVStore

type KVStore struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       KVStoreSpec   `json:"spec"`
	Status     KVStoreStatus `json:"status,omitempty"`
}

KVStore is a namespaced, owned KV resource (ADR-0072, reshaped by ADR-0073): a named domain with per-op caps, a set of sub-domains (tables) each with a single-writer owner, and a Ready lifecycle. A function reaches a table only through a Function.spec.kv binding (default-deny); the table's owner is the single writer. The store is one Badger prefix <ns>/<store>/; a table is <ns>/<store>/<table>/. Deletion-protected by referencing bindings and by non-empty data.

func (*KVStore) GetStatus

func (s *KVStore) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject (the controller's write-back seam).

func (*KVStore) GroupVersionKind

func (s *KVStore) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for KVStore.

func (*KVStore) Validate

func (s *KVStore) Validate() error

Validate performs envelope validation via the shared validateMeta helper, then the KVStoreSpec rules JSON Schema can't express: the caps are non-negative (0 ⇒ default), maxValueBytes is at most MaxValueBytesLimit and maxKeyBytes at most MaxKeyBytesLimit; and within the store, table names are unique (⇒ a table has exactly one owner) and each is a DNS-1123 label. Cross-resource rules (the owner exists) are an admission (ADR-0073), not structural Validate.

type KVStoreSpec

type KVStoreSpec struct {
	// MaxValueBytes caps a single value's size; 0 ⇒ DefaultMaxValueBytes (1 MiB); at most MaxValueBytesLimit.
	MaxValueBytes int64 `json:"maxValueBytes,omitempty" minimum:"0" maximum:"1048576"`
	// MaxKeyBytes caps a single key's size; 0 ⇒ DefaultMaxKeyBytes (1 KiB); at most MaxKeyBytesLimit.
	MaxKeyBytes int `json:"maxKeyBytes,omitempty" minimum:"0" maximum:"64000"`
	// Tables are the store's sub-domains (ADR-0073): each is a key space <ns>/<store>/<table>/ with a
	// single-writer Owner. Table names are unique within the store (so a table has exactly one owner by
	// construction). Empty ⇒ a store with no writable sub-domains.
	Tables []KVTable `json:"tables,omitempty"`
}

KVStoreSpec is the desired state of a KVStore (ADR-0072/0073): the per-op caps the facade enforces before a write reaches the driver, and the store's sub-domains (tables). A 0 cap means "use the default" (read at enforcement time).

func (KVStoreSpec) EffectiveMaxKeyBytes

func (s KVStoreSpec) EffectiveMaxKeyBytes() int

EffectiveMaxKeyBytes returns the per-key cap, applying the default when the spec is 0 and clamping to MaxKeyBytesLimit: a store persisted before Validate enforced the limit is never re-validated.

func (KVStoreSpec) EffectiveMaxValueBytes

func (s KVStoreSpec) EffectiveMaxValueBytes() int64

EffectiveMaxValueBytes returns the per-value cap, applying the default when the spec is 0 and clamping to MaxValueBytesLimit: a store persisted before Validate enforced the limit is never re-validated.

type KVStoreStatus

type KVStoreStatus struct {
	Status `json:",inline"`
	// Tables is the number of sub-domains declared on the store (computed by the reconciler).
	Tables int `json:"tables,omitempty"`
	// Bindings is the number of Function.spec.kv entries referencing this store (computed by the reconciler).
	Bindings int `json:"bindings,omitempty"`
}

KVStoreStatus is the observed state of a KVStore (ADR-0072/0073): the reconciler sets Ready and the count of tables + the count of Function.spec.kv bindings referencing it. It embeds the shared Status (Phase + Conditions) so the controller's generic write-back seam (StatusObject.GetStatus) points at the live status.

type KVTable

type KVTable struct {
	// Name is the sub-domain name; a DNS-1123 label, unique within the store.
	Name string `json:"name" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
	// Owner is the single writer: a Function in this store's namespace. Empty ⇒ no writer (read-only
	// through the facade). Cross-resource validity (the owner exists) is an admission, not Validate.
	Owner ObjectName `json:"owner,omitempty"`
}

KVTable is one sub-domain of a KVStore (ADR-0073): a named key space with a single-writer owner. The typed-record engine (backlog) attaches its Schema/Indexes here (table-scoped) without a re-model.

type Kind

type Kind string

Kind is the typed set of resource kinds.

const (
	KindNamespace      Kind = "Namespace"
	KindResourceGroup  Kind = "ResourceGroup"
	KindFunction       Kind = "Function"
	KindRevision       Kind = "Revision"
	KindRoute          Kind = "Route"
	KindService        Kind = "Service"
	KindEventSource    Kind = "EventSource"
	KindConfigMap      Kind = "ConfigMap"
	KindSecret         Kind = "Secret"
	KindGrant          Kind = "Grant"
	KindEgressPolicy   Kind = "EgressPolicy"
	KindInvocation     Kind = "Invocation"
	KindRuntimeClass   Kind = "RuntimeClass"
	KindWorkerNode     Kind = "WorkerNode"
	KindGateway        Kind = "Gateway"
	KindKVStore        Kind = "KVStore"
	KindBucket         Kind = "Bucket"
	KindCatalogService Kind = "CatalogService"
	KindPolicy         Kind = "Policy"
	KindWorkflow       Kind = "Workflow"
	KindWorkflowRun    Kind = "WorkflowRun"
	KindSensor         Kind = "Sensor"
	// KindIdentity is a user-assigned managed identity (ADR-0135, F100): a stored, status-bearing CRUD
	// resource whose reconciler issues a credential. It resolves on the wire to an S3Identity Cedar
	// principal (KindS3Identity below is the auth-only wire principal; Identity is the CRUD resource).
	KindIdentity Kind = "Identity"
	// KindRole (ADR-0136, F101) is a named data-plane permission set (a stored value-type, like Grant).
	KindRole Kind = "Role"
	// KindRolesAssignment (ADR-0136, F101) grants many (principal, role, scope) entries in one stored
	// value-type; the PDP compiles it to Cedar permits + the single-writer `writers` set.
	KindRolesAssignment Kind = "RolesAssignment"
	// KindSite (ADR-0139, F103) is a declarative static web app: an immutable bundle materialized into a
	// digest-scoped Bucket prefix, owning its Bucket + Route inline; Ready only once servable.
	KindSite Kind = "Site"
	// KindS3Identity is the external SigV4 S3 principal (ADR-0080): NOT a stored/CRUD resource —
	// it has no metastore registration (no NewObject/AllKinds/handlers), it exists only as a Cedar
	// principal type the cedar driver materializes for the external-sigv4 authz path. It is excluded
	// from Kind.Validate's known-CRUD set by design.
	KindS3Identity Kind = "S3Identity"
	// KindNetDestination is the ephemeral egress destination a worker connects to (ADR-0117, F81):
	// an AUTHORIZATION-ONLY kind (the exact KindS3Identity precedent) — NOT a stored/CRUD resource, so
	// it has no metastore registration (excluded from Kind.Validate's CRUD set / NewObject / AllKinds).
	// It exists only as the Cedar resource type the egress capability materializes for an egress::connect
	// decision. Its EntityRef reinterprets the fields: the destination rides the plain-string Path,
	// PINNED encoding Path = "<dst-ip>:<port>#<domain1>,<domain2>,…" (the "#…" domain segment is the
	// forwarder-attested set, empty for a pure-IP/CIDR target); Name/Namespace are unused.
	KindNetDestination Kind = "NetDestination"
)

func AllKinds

func AllKinds() []Kind

AllKinds returns all kinds in a stable order.

func (Kind) GVK

func (k Kind) GVK() GroupVersionKind

GVK returns the GroupVersionKind for this kind.

func (Kind) Namespaced

func (k Kind) Namespaced() bool

Namespaced reports whether this kind is namespaced. Cluster-scoped kinds: Namespace, RuntimeClass, WorkerNode, Gateway.

func (Kind) Validate

func (k Kind) Validate() error

Validate returns fault.Invalid if the Kind is not one of the known kinds.

type Namespace

type Namespace struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       NamespaceSpec   `json:"spec,omitempty"`
	Status     NamespaceStatus `json:"status,omitempty"`
}

Namespace is a cluster-scoped resource that defines a tenant boundary. Status-bearing.

func (*Namespace) GetStatus

func (n *Namespace) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*Namespace) GroupVersionKind

func (n *Namespace) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Namespace.

func (*Namespace) Validate

func (n *Namespace) Validate() error

Validate performs envelope + spec validation.

type NamespaceName

type NamespaceName string

NamespaceName is a DNS-label-qualified namespace identifier.

func (NamespaceName) Schema

Schema carries NamespaceName's DNS-1123 constraint into the generated OpenAPI.

func (NamespaceName) Validate

func (n NamespaceName) Validate() error

Validate checks the NamespaceName against DNS-label rules.

type NamespaceSpec

type NamespaceSpec struct {
	// DefaultExposure switches the public data-plane front door. Empty/absent ⇒ implicit.
	DefaultExposure ExposureMode `json:"defaultExposure,omitempty"`
	// EdgeDefaults carries the namespace-wide edge policy defaults merged under each Route
	// (F74–F78 add fields; empty in F79).
	EdgeDefaults *EdgeDefaults `json:"edgeDefaults,omitempty"`
}

NamespaceSpec is the tenant's edge posture (ADR-0110, F79). A Spec-less namespace (the pre-F79 shape) has the zero value, which normalizes to `implicit` — so existing deployments are unchanged on upgrade.

type NamespaceStatus

type NamespaceStatus struct {
	Status `json:",inline"`
}

NamespaceStatus holds the observed state.

type OCIPlatform added in v0.2.0

type OCIPlatform string

OCIPlatform is an OCI platform "<os>/<architecture>", e.g. "linux/arm64" (ADR-0145): the platform a function artifact was built for, or the platform a worker node runs.

const (
	PlatformLinuxAMD64 OCIPlatform = "linux/amd64"
	PlatformLinuxARM64 OCIPlatform = "linux/arm64"
)

The platforms `funcdctl push --platform` accepts for a function artifact (ADR-0145).

func HostPlatform added in v0.2.0

func HostPlatform() OCIPlatform

HostPlatform is the daemon's own GOOS/GOARCH.

func (OCIPlatform) Arch added in v0.2.0

func (p OCIPlatform) Arch() string

Arch is the platform's CPU architecture ("" when p is not valid).

func (OCIPlatform) OS added in v0.2.0

func (p OCIPlatform) OS() string

OS is the platform's operating system ("" when p is not valid).

func (OCIPlatform) Validate added in v0.2.0

func (p OCIPlatform) Validate() error

Validate checks the "<os>/<arch>" shape: two non-empty segments, no variant.

type Object

type Object interface {
	GroupVersionKind() GroupVersionKind
	GetObjectMeta() *ObjectMeta
	GetName() ObjectName
	GetNamespace() NamespaceName
	GetResourceGroup() ResourceGroupName
	GetGeneration() int64
	Validate() error
}

Object is the generic interface satisfied by every resource kind. The store persists and the controller watches through this interface — no per-kind switch.

func NewObject

func NewObject(k Kind) (Object, bool)

NewObject returns a zero-valued typed Object for the given kind with TypeMeta stamped. Returns false if the kind is unknown.

type ObjectMeta

type ObjectMeta struct {
	// Name is the resource name. omitempty (not "required") so a create may omit it in favour of
	// GenerateName; the store still requires a non-empty Name (ObjectMeta.Validate) once assigned.
	Name ObjectName `json:"name,omitempty"`
	// GenerateName is an optional NAME PREFIX for server-side name generation (the k8s pattern): when Name
	// is empty and GenerateName is set, the create path fills Name = GenerateName + a random suffix
	// (GenerateObjectName), retrying on the rare collision. Ignored once Name is set. A plain prefix string
	// (a trailing '-' is idiomatic and allowed — the generated Name is what must be a valid label).
	GenerateName    string            `json:"generateName,omitempty" pattern:"^[a-z0-9][a-z0-9-]{0,62}$"`
	Namespace       NamespaceName     `json:"namespace,omitempty"`
	ResourceGroup   ResourceGroupName `json:"resourceGroup,omitempty"`
	Tags            Tags              `json:"tags,omitempty"`
	UID             UID               `json:"uid,omitempty"`
	Generation      int64             `json:"generation,omitempty"`
	ResourceVersion string            `json:"resourceVersion,omitempty"`
	CreationTime    time.Time         `json:"creationTimestamp,omitempty"`
	DeletionTime    *time.Time        `json:"deletionTimestamp,omitempty"`
	OwnerReferences []OwnerReference  `json:"ownerReferences,omitempty"`
	Finalizers      []string          `json:"finalizers,omitempty"`
}

ObjectMeta is the shared metadata embedded by every resource kind. resourceGroup is required for namespaced kinds (F22); tags are optional. Carrier bookkeeping fields (UID, Generation, ResourceVersion, …) are set by the store; their lifecycle semantics are owned by the store/controller ADRs.

func (*ObjectMeta) GetGeneration

func (m *ObjectMeta) GetGeneration() int64

GetGeneration returns the current generation.

func (*ObjectMeta) GetName

func (m *ObjectMeta) GetName() ObjectName

GetName returns the resource name.

func (*ObjectMeta) GetNamespace

func (m *ObjectMeta) GetNamespace() NamespaceName

GetNamespace returns the namespace (empty for cluster-scoped kinds).

func (*ObjectMeta) GetObjectMeta

func (m *ObjectMeta) GetObjectMeta() *ObjectMeta

GetObjectMeta returns the ObjectMeta pointer for generic store/admission stamping.

func (*ObjectMeta) GetResourceGroup

func (m *ObjectMeta) GetResourceGroup() ResourceGroupName

GetResourceGroup returns the resource group.

func (*ObjectMeta) Validate

func (m *ObjectMeta) Validate(k Kind) error

Validate checks the ObjectMeta against envelope rules. Scope is derived from k.Namespaced() — the kind is the single source of scope.

type ObjectName

type ObjectName string

ObjectName is a DNS-1123-label-qualified resource name.

func GenerateObjectName

func GenerateObjectName(prefix string) ObjectName

GenerateObjectName builds a unique object name from a prefix: the prefix (truncated so the whole name stays within the 63-char DNS-1123 label limit) followed by a random 8-hex-char suffix. It is the single name-generation convention for server-side ObjectMeta.GenerateName and the Sensor's WorkflowRun names.

func StepFunctionName added in v0.6.1

func StepFunctionName(workflow, step ObjectName) ObjectName

StepFunctionName is the name of the Function an image step materializes into: <workflow>-<step> (ADR-0094).

func (ObjectName) Schema

func (ObjectName) Schema(huma.Registry) *huma.Schema

Schema makes ObjectName carry its DNS-1123 constraint into the generated OpenAPI (huma SchemaProvider) — the same pattern Validate() enforces. Every field typed ObjectName inherits it.

func (ObjectName) Validate

func (n ObjectName) Validate() error

Validate checks the ObjectName against DNS-label rules.

type ObjectRef

type ObjectRef struct {
	Kind      Kind          `json:"kind"`
	Namespace NamespaceName `json:"namespace,omitempty"`
	Name      ObjectName    `json:"name"`
}

ObjectRef addresses an object within the single v1alpha1 group/version. Cross-version refs (the v1 graduation) would add an apiVersion field.

type OwnerReference

type OwnerReference struct {
	ObjectRef          `json:",inline"`
	UID                UID  `json:"uid"`
	Controller         bool `json:"controller,omitempty"`
	BlockOwnerDeletion bool `json:"blockOwnerDeletion,omitempty"`
}

OwnerReference establishes a parent-child relationship between resources.

func ControllerOf added in v0.4.0

func ControllerOf(refs []OwnerReference) (OwnerReference, bool)

ControllerOf returns the controller OwnerReference of refs, the first one marked Controller.

type PathType

type PathType string

PathType selects exact vs segment-prefix matching.

const (
	PathTypePrefix PathType = "Prefix"
	PathTypeExact  PathType = "Exact"
)

func (PathType) Schema

func (PathType) Schema(huma.Registry) *huma.Schema

Schema renders the huma enum for PathType (empty is accepted and defaults to Prefix).

type Phase

type Phase string

Phase represents the lifecycle phase of a resource per the blueprint resource state machine. Reconciled by ADR-0003 from the ADR-0002 scaffold placeholders.

const (
	PhasePending     Phase = "Pending"
	PhaseDeploying   Phase = "Deploying"
	PhaseReady       Phase = "Ready"
	PhaseIdle        Phase = "Idle"
	PhaseDegraded    Phase = "Degraded"
	PhaseFailed      Phase = "Failed"
	PhaseTerminating Phase = "Terminating"
)

func (Phase) IsTerminal

func (p Phase) IsTerminal() bool

IsTerminal reports whether the phase is terminal (no further transitions expected). Only PhaseTerminating is terminal — it is the sole state with no live successor.

func (Phase) Schema

func (Phase) Schema(huma.Registry) *huma.Schema

Schema carries Phase's enum constraint into the generated OpenAPI (huma SchemaProvider) — the same closed set Validate() enforces, declared once from the Phase consts.

func (Phase) String

func (p Phase) String() string

String returns the string representation of the Phase.

func (Phase) Validate

func (p Phase) Validate() error

Validate checks that the Phase is a known value.

type Policy

type Policy struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       PolicySpec `json:"spec"`
}

Policy is a namespaced authorization resource (ADR-0074): its spec is Cedar policy text (one or more permit/forbid statements) the cedar driver (internal/auth/cedar) compiles into the PDP's PolicySet. It is how an operator grants a function fine-grained resource access — e.g. permit a Function to kv::read a KVStore. Reads are DEFAULT-DENY: with no permitting Policy, a kv::read is Forbidden; owner-write is a built-in rule (not a user Policy). Structural Validate checks the envelope + that the text is non-empty; the Cedar parse + curated-schema check is the policy-validity admission (ADR-0063), which the driver relies on so a stored Policy compiles.

func (*Policy) GroupVersionKind

func (p *Policy) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Policy.

func (*Policy) Validate

func (p *Policy) Validate() error

Validate performs envelope validation via the shared validateMeta helper, then the one structural rule JSON Schema can't express: spec.cedar is non-empty. The Cedar parse + curated-schema check is the policy-validity admission (ADR-0074), not structural Validate.

type PolicySpec

type PolicySpec struct {
	// Cedar is one or more Cedar permit/forbid statements (validated by the policy-validity admission
	// against the curated action/entity schema — kv::read/kv::write; Function/KVStore/KVTable).
	Cedar string `json:"cedar"`
}

PolicySpec is the desired state of a Policy (ADR-0074): the Cedar policy text.

type Pooling

type Pooling struct {
	// Worker is an owner-chosen worker id. Empty ⇒ solo (own worker). Functions sharing
	// (namespace, runtime, Worker) co-locate as handlers in one worker_threads pool worker.
	Worker string `json:"worker,omitempty"`
}

Pooling is the per-function pooling opt-in (ADR-0046, F28). Named "Pooling" (not "Placement") to stay clear of scheduler.Placement (node selection, ADR-0017): pooling answers which shared worker within a node a function joins.

type PoolingMode

type PoolingMode string

PoolingMode selects shared-pool vs isolated-container materialization.

const (
	// PoolingShared co-locates same-runtime image steps in one worker pool (default).
	PoolingShared PoolingMode = "shared"
	// PoolingIsolated gives each step its own solo worker/container.
	PoolingIsolated PoolingMode = "isolated"
)

func (PoolingMode) Schema

func (PoolingMode) Schema(huma.Registry) *huma.Schema

Schema carries PoolingMode's enum into the generated OpenAPI (ADR-0048).

type PrincipalKind

type PrincipalKind string

PrincipalKind is the kind of a principal a role is assigned to.

const (
	// PrincipalKindFunction is a Function's system-assigned identity.
	PrincipalKindFunction PrincipalKind = "Function"
	// PrincipalKindIdentity is a user-assigned managed Identity (ADR-0135).
	PrincipalKindIdentity PrincipalKind = "Identity"
)

type PrincipalObject

type PrincipalObject interface {
	// contains filtered or unexported methods
}

PrincipalObject is a resolved principal-backing object for the cedar capability registry (ADR-0116): a *Function or a *CatalogService whose declared bindings (spec.kv/links/blob) are materialized onto the Cedar principal. It is a CLOSED interface — its marker method is unexported, so only types in this package implement it, which lets the registry's Bind funcs type-switch on it without any.

type PrincipalRef

type PrincipalRef struct {
	Kind PrincipalKind `json:"kind" enum:"Function,Identity"`
	Name ObjectName    `json:"name"`
}

PrincipalRef names the grantee: a typed {kind, name}. This is the "principal side is no longer Function-only" generalization (ADR-0135/0136).

type ReplaySeed

type ReplaySeed struct {
	// Run is the source run to replay (same namespace).
	Run ObjectName `json:"run"`
	// From is the step to re-run from; `from` and its descendants re-execute, upstream steps are reused.
	From ObjectName `json:"from"`
	// AllowDrift opts into re-running steps whose resolved artifact digest moved since the source run
	// (a re-materialized workflow) — "same data, current code". Default false ⇒ drift is rejected.
	AllowDrift bool `json:"allowDrift,omitempty"`
}

ReplaySeed re-runs a finished source run from a chosen step (ADR-0107, F71): a new run seeded from the source's recorded checkpoint. Set by `funcdctl workflow replay`; observed by the run reconciler.

type ResourceGroup

type ResourceGroup struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       ResourceGroupSpec   `json:"spec"`
	Status     ResourceGroupStatus `json:"status,omitempty"`
}

ResourceGroup is a namespaced resource for logical grouping of resources. Status-bearing.

func (*ResourceGroup) GetStatus

func (rg *ResourceGroup) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*ResourceGroup) GroupVersionKind

func (rg *ResourceGroup) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for ResourceGroup.

func (*ResourceGroup) Validate

func (rg *ResourceGroup) Validate() error

Validate performs envelope validation via the shared validateMeta helper.

type ResourceGroupName

type ResourceGroupName string

ResourceGroupName is a DNS-1123-label-qualified resource group identifier.

func (ResourceGroupName) Schema

Schema carries ResourceGroupName's DNS-1123 constraint into the generated OpenAPI.

func (ResourceGroupName) Validate

func (n ResourceGroupName) Validate() error

Validate checks the ResourceGroupName against DNS-label rules.

type ResourceGroupSpec

type ResourceGroupSpec struct {
	Description string `json:"description,omitempty"`
}

ResourceGroupSpec holds the desired state. Behavioral fields (cascade-delete behavior) owned by controller ADR (F08).

type ResourceGroupStatus

type ResourceGroupStatus struct {
	Status `json:",inline"`
}

ResourceGroupStatus holds the observed state.

type ResourceSpec

type ResourceSpec struct {
	// CPU is a recorded CPU request/limit hint (e.g. "2"); forward-compat only.
	CPU string `json:"cpu,omitempty"`
	// Memory is a recorded memory request/limit hint (e.g. "4Gi"); forward-compat only.
	Memory string `json:"memory,omitempty"`
}

ResourceSpec sizes the backing engine (cpu/mem). RECORDED ONLY on the CatalogService (ADR-0086): FunctionSpec has no resources field today, so this is forward-compat (the same posture as Scaling.MaxReplicas) and is never projected onto the materialized Function.

type Revision

type Revision struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       RevisionSpec   `json:"spec"`
	Status     RevisionStatus `json:"status,omitempty"`
}

Revision is a namespaced, immutable snapshot of a Function at a point in time. Status-bearing. Behavioral fields (frozen snapshot payload) owned by F13.

func (*Revision) GetStatus

func (r *Revision) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*Revision) GroupVersionKind

func (r *Revision) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Revision.

func (*Revision) Validate

func (r *Revision) Validate() error

Validate performs envelope validation via the shared validateMeta helper.

type RevisionID

type RevisionID string

RevisionID is a unique identifier for a function revision.

func (RevisionID) Validate

func (r RevisionID) Validate() error

Validate checks that the RevisionID is non-empty.

type RevisionPin added in v0.7.0

type RevisionPin struct {
	Function    ObjectName `json:"function"`
	FunctionUID UID        `json:"functionUID"`
	Revision    ObjectName `json:"revision"`
	ImageDigest string     `json:"imageDigest,omitempty"` // empty only for a file:// artifact
}

RevisionPin binds a run to one step Function revision (ADR-0190).

type RevisionSpec

type RevisionSpec struct {
	Function    ObjectRef   `json:"function"`
	Number      int64       `json:"number" minimum:"1"`
	Runtime     RuntimeName `json:"runtime,omitempty"`
	Handler     string      `json:"handler,omitempty" pattern:"^[A-Za-z_][A-Za-z0-9_.]*$"`
	Image       string      `json:"image,omitempty"`
	ImageDigest string      `json:"imageDigest,omitempty" pattern:"^sha256:[a-f0-9]{64}$"`
}

RevisionSpec holds the immutable identity + frozen snapshot of a revision. Number is the revision sequence number. The Runtime/Handler/Image snapshot (F13/ADR-0020, flattened by ADR-0097) pins "what was validated ships" — immutable once stamped.

type RevisionStatus

type RevisionStatus struct {
	Status `json:",inline"`
}

RevisionStatus holds the observed state.

type Role

type Role struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       RoleSpec `json:"spec"`
}

Role is a named, reusable permission set (ADR-0136, FEAT-0008/F101): a set of funcd data-plane action strings a RolesAssignment grants to a principal at a scope. Custom roles complement the fixed built-in catalog (Blob Data Reader/Writer, KV Data Reader/Writer, Function Invoker, Reader/Contributor/Owner). A pure value-type (no status), like Grant — the PDP compiles it, the reconciler does not touch it.

func (*Role) GroupVersionKind

func (r *Role) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Role.

func (*Role) Validate

func (r *Role) Validate() error

Validate performs envelope + structural validation: at least one action.

type RoleRef

type RoleRef struct {
	Kind RoleRefKind `json:"kind" enum:"BuiltinRole,Role"`
	Name string      `json:"name"`
}

RoleRef names the role: a built-in name or a custom Role.

type RoleRefKind

type RoleRefKind string

RoleRefKind selects a built-in role by name or a custom Role resource.

const (
	// RoleRefKindBuiltin references a built-in role by name (e.g. "Blob Data Writer").
	RoleRefKindBuiltin RoleRefKind = "BuiltinRole"
	// RoleRefKindRole references a custom Role resource by name.
	RoleRefKindRole RoleRefKind = "Role"
)

type RoleSpec

type RoleSpec struct {
	Actions []string `json:"actions"`
}

RoleSpec is the action set. Actions are funcd data-plane action strings ("s3::read", "s3::write", "kv::read", "kv::write", "link::invoke") — kept as strings so api/types imports no internal package.

type RolesAssignment

type RolesAssignment struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       RolesAssignmentSpec `json:"spec"`
}

RolesAssignment grants MANY roles in one object (ADR-0136, FEAT-0008/F101): each entry is a (principal, role, scope) triple with optional top-level principal/scope defaults — no per-role sprawl. A pure value-type (no status): the PDP compiles read/query/invoke entries to Cedar permits and the write entries to the single-writer `writers` set.

func (*RolesAssignment) GroupVersionKind

func (ra *RolesAssignment) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for RolesAssignment.

func (*RolesAssignment) Validate

func (ra *RolesAssignment) Validate() error

Validate performs envelope + structural validation: every entry resolves a principal + role + scope (own or default), with valid kinds.

type RolesAssignmentSpec

type RolesAssignmentSpec struct {
	Principal   *PrincipalRef     `json:"principal,omitempty"`
	Scope       *ScopeRef         `json:"scope,omitempty"`
	Assignments []AssignmentEntry `json:"assignments"`
}

RolesAssignmentSpec carries the default principal/scope + the assignment entries.

type Route

type Route struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       RouteSpec   `json:"spec"`
	Status     RouteStatus `json:"status,omitempty"`
}

Route is a namespaced resource that declares the edge exposure of one or more Functions (ADR-0110, F79): which Functions are reachable at the edge (host/path → Function) and — via the per-route policy fields added by F74–F78 — how. Status-bearing; Ready once every rule's backend Function exists and the route is programmed into the edge router.

func (*Route) GetStatus

func (r *Route) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*Route) GroupVersionKind

func (r *Route) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Route.

func (*Route) Validate

func (r *Route) Validate() error

Validate performs envelope + semantic validation. It is namespace-agnostic: the host-required-in-explicit and cross-namespace (host,path,method) collision rules depend on the namespace mode and the full Route set, so the reconciler enforces those (→ NotReady), not here.

type RouteAuth

type RouteAuth struct {
	Mode AuthMode `json:"mode,omitempty"`
}

RouteAuth is the F77 auth stance on a Route.

type RouteBackend

type RouteBackend struct {
	// Function is the target Function in this Route's namespace. Optional since F82: a static-only
	// rule sets no function (the `omitempty` reflects the union — exactly one arm is set).
	Function ObjectName `json:"function,omitempty"`
	// Static serves a Bucket-prefix static site directly through the edge (F82); nil ⇒ a function backend.
	Static *StaticBackend `json:"static,omitempty"`
}

RouteBackend is an exactly-one-of union (ADR-0120, F82): a Function backend (the activator hop) OR a Static backend (a Bucket prefix served directly through the edge). Validate enforces the one-of. Routes are never shared across namespaces (blueprint.md:467).

type RouteRule

type RouteRule struct {
	Path     string       `json:"path"`               // must begin "/"
	PathType PathType     `json:"pathType,omitempty"` // Exact | Prefix (default Prefix)
	Methods  []HTTPMethod `json:"methods,omitempty"`  // empty ⇒ all methods
	Backend  RouteBackend `json:"backend"`
}

RouteRule matches a path (+ optional methods) and names the backend Function.

type RouteSpec

type RouteSpec struct {
	// Host is an exact host match; "" matches any host. In an `explicit`-mode namespace the
	// reconciler requires a non-empty Host (the tenant discriminator, ADR-0110).
	Host string `json:"host,omitempty"`
	// Rules lists the path rules, matched longest-prefix-first. At least one is required.
	Rules []RouteRule `json:"rules"`
	// Auth is the edge authentication stance for this Route (ADR-0113, F77). nil ⇒ inherit the
	// namespace default; unset overall ⇒ open (phased). Applies to all Rules (per-rule auth is V2).
	Auth *RouteAuth `json:"auth,omitempty"`
}

RouteSpec is the declarative edge exposure. V1 carries matching + backend + the F77 auth stance; the remaining policy fields (tls/limits/observability/cors) are added by F74/F75/F76/F78.

type RouteStatus

type RouteStatus struct {
	Status `json:",inline"`
}

RouteStatus holds the observed state (Ready / NotReady with reason BackendNotFound | HostRequired | RouteConflict, set by the reconciler).

type RunPhase added in v0.6.1

type RunPhase string

RunPhase is a run's execution phase (ADR-0094): Pending → Running ⇄ Paused → Succeeded | Failed | Cancelled.

const (
	RunPending   RunPhase = "Pending"
	RunRunning   RunPhase = "Running"
	RunPaused    RunPhase = "Paused"
	RunSucceeded RunPhase = "Succeeded"
	RunFailed    RunPhase = "Failed"
	RunCancelled RunPhase = "Cancelled"
)

func (RunPhase) Schema added in v0.6.1

func (RunPhase) Schema(huma.Registry) *huma.Schema

Schema carries RunPhase's enum into the generated OpenAPI (ADR-0048).

type RunStepStatus

type RunStepStatus struct {
	Name     ObjectName `json:"name"`
	Phase    StepPhase  `json:"phase,omitempty"`
	Attempts int        `json:"attempts,omitempty"`
	Revision string     `json:"revision,omitempty"`
	// StartedAt/EndedAt (unix nanos) give the step duration; Error is the raw step-level failure
	// cause, capped — the full text lives in the step's span + logs (ADR-0106) — on a Failed step, or
	// the cancel on a step that was running when the run was cancelled (ADR-0146).
	StartedAt int64  `json:"startedAt,omitempty"`
	EndedAt   int64  `json:"endedAt,omitempty"`
	Error     string `json:"error,omitempty"`
}

RunStepStatus is one step's coarse execution state, including the ADR-0100 troubleshooting facts (timings → duration, populated attempt count, and the capped step-level failure cause).

type RuntimeClass

type RuntimeClass struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       RuntimeClassSpec   `json:"spec"`
	Status     RuntimeClassStatus `json:"status,omitempty"`
}

RuntimeClass is a cluster-scoped resource defining a function runtime environment. Status-bearing. Behavioral fields (flavor params) owned by F12.

func (*RuntimeClass) GetStatus

func (rc *RuntimeClass) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*RuntimeClass) GroupVersionKind

func (rc *RuntimeClass) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for RuntimeClass.

func (*RuntimeClass) Validate

func (rc *RuntimeClass) Validate() error

Validate performs envelope validation via the shared validateMeta helper.

type RuntimeClassSpec

type RuntimeClassSpec struct {
	Handler string `json:"handler,omitempty" pattern:"^[A-Za-z_][A-Za-z0-9_.]*$"`
}

RuntimeClassSpec holds the desired state. Behavioral fields owned by F12.

type RuntimeClassStatus

type RuntimeClassStatus struct {
	Status `json:",inline"`
}

RuntimeClassStatus holds the observed state.

type RuntimeName

type RuntimeName string

RuntimeName is a DNS-label-qualified RuntimeClass name reference (FunctionSpec.Runtime, RevisionSpec.Runtime) — ADR-0048. Typed so its DNS-1123 constraint reaches both the generated OpenAPI (Schema) and the admission check (Validate) from one declaration.

func (RuntimeName) Schema

func (RuntimeName) Schema(huma.Registry) *huma.Schema

Schema carries RuntimeName's DNS-1123 constraint into the generated OpenAPI.

func (RuntimeName) Validate

func (n RuntimeName) Validate() error

Validate checks the RuntimeName is non-empty and a valid DNS label.

type Scaling

type Scaling struct {
	MinReplicas int           `json:"minReplicas,omitempty" minimum:"0" maximum:"15"`             // 0 enables scale-to-zero
	MaxReplicas int           `json:"maxReplicas,omitempty" minimum:"0" maximum:"15"`             // recorded; 1→N enforcement is V3
	IdleTimeout time.Duration `json:"idleTimeout,omitempty" minimum:"0" maximum:"86400000000000"` // reclaim delay, int64 ns; 0≤≤24h, 0 disables
}

Scaling is the F11 scale-to-zero policy on a Function (ADR-0016). Field validation (non-negative, MinReplicas ≤ MaxReplicas) is the API server's admission job (P-L/F07); the activator reads these defensively.

type SchemaView

type SchemaView struct {
	Type     string
	Props    map[string]string          // property name → primitive type
	Defaults map[string]json.RawMessage // property name → declared default, for the properties that have one
	Required []string
}

SchemaView is the F65-relevant subset of a JSON Schema: a type, typed top-level properties, their declared defaults (ADR-0095), and the required set. A void schema is type "null" (or empty/absent — nothing required).

func ParseSchemaView

func ParseSchemaView(raw json.RawMessage) SchemaView

ParseSchemaView reads the F65-relevant fields from a JSON Schema (tolerant: unknown keywords ignored).

func (SchemaView) IsVoid

func (s SchemaView) IsVoid() bool

IsVoid reports whether a schema declares no data (a null-typed or empty schema — ADR-0090 void).

type ScopeKind

type ScopeKind string

ScopeKind is the granularity a grant applies at.

const (
	// ScopeKindNamespace scopes a grant to every resource in a namespace (inherits down).
	ScopeKindNamespace ScopeKind = "Namespace"
	// ScopeKindBucketPrefix scopes a grant to one blob prefix ("<bucket>/<prefix>").
	ScopeKindBucketPrefix ScopeKind = "BucketPrefix"
	// ScopeKindKVStore scopes a grant to one KV store (or "<store>/<table>").
	ScopeKindKVStore ScopeKind = "KVStore"
	// ScopeKindCatalog scopes a grant to one catalog serving layer ("<catalog>") — ADR-0137, F102.
	ScopeKindCatalog ScopeKind = "Catalog"
)

type ScopeRef

type ScopeRef struct {
	Kind ScopeKind `json:"kind" enum:"Namespace,BucketPrefix,KVStore,Catalog"`
	Name string    `json:"name,omitempty"`
}

ScopeRef names the scope: a namespace, a bucket prefix, or a kv store. Name is the scope-relative name ("<bucket>/<prefix>" for BucketPrefix; the namespace is the assignment's own namespace).

type Secret

type Secret struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       SecretSpec `json:"spec"`
}

Secret is a namespaced, pure-data resource for sensitive configuration. Secret does NOT have status — it implements Object, not StatusObject.

func (*Secret) GroupVersionKind

func (s *Secret) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Secret.

func (*Secret) Validate

func (s *Secret) Validate() error

Validate performs envelope validation, then the data-key rule JSON Schema can't express (ADR-0048): every data key is an env-var name. The `type` enum is schema-enforced at the edge.

type SecretSpec

type SecretSpec struct {
	Type SecretType        `json:"type,omitempty"`
	Data map[string][]byte `json:"data,omitempty"`
}

SecretSpec holds the secret data. SecretType is an open typed-string discriminator whose enumerated values are owned by the secrets ADR (F15).

type SecretType

type SecretType string

SecretType is an open typed-string discriminator for secret kinds. Enumerated values are defined by the secrets ADR (F15).

const (
	// SecretTypeOpaque is the default generic key/value secret (ADR-0022, F15).
	SecretTypeOpaque SecretType = "Opaque"
)

func (SecretType) Schema

func (SecretType) Schema(huma.Registry) *huma.Schema

Schema carries SecretType's enum constraint into the generated OpenAPI (ADR-0048).

type Sensor

type Sensor struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       SensorSpec   `json:"spec"`
	Status     SensorStatus `json:"status,omitempty"`
}

Sensor is the reusable event→action binder (ADR-0109, F69): it subscribes named event dependencies (`spec.on`, tuple-addressed `(source, event)`) and, on a firing, runs kind-keyed actions (`spec.do` — `workflow:` start a run · `function:` invoke), projecting the firing CloudEvent into the target's input. Namespaced, status-bearing. Shared by Functions and Workflows.

func (*Sensor) GetStatus

func (s *Sensor) GetStatus() *Status

GetStatus returns the shared Status pointer (the controller write-back seam).

func (*Sensor) GroupVersionKind

func (s *Sensor) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Sensor.

func (*Sensor) Validate

func (s *Sensor) Validate() error

Validate enforces the wiring rules JSON Schema can't express (ADR-0109/ADR-0048): unique dependency and action names; each action bound to a declared dependency and exactly one action kind; DNS-1123 labels for source/event/workflow/function. (The `${{ }}` input parse+check is a reconcile-time step — it needs the F73 engine — not a Validate rule.)

type SensorSpec

type SensorSpec struct {
	// On lists the named event dependencies this Sensor subscribes to (≥1, unique names).
	On []Dependency `json:"on"`
	// Do lists the named actions (≥1, unique names); each is bound to one dependency via On.
	Do []Action `json:"do"`
}

SensorSpec binds event dependencies to actions (ADR-0109).

type SensorStatus

type SensorStatus struct {
	Status `json:",inline"`
}

SensorStatus holds the observed state (Ready/NotReady with a reason).

type Service

type Service struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       ServiceSpec   `json:"spec"`
	Status     ServiceStatus `json:"status,omitempty"`
}

Service is a namespaced resource representing a platform service binding. Status-bearing. Behavioral spec fields (driver config, binding) owned by F14/F23.

func (*Service) GetStatus

func (s *Service) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*Service) GroupVersionKind

func (s *Service) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Service.

func (*Service) Validate

func (s *Service) Validate() error

Validate performs envelope validation, then the cross-field rules JSON Schema can't express (ADR-0048): the sub-spec present iff its discriminator matches, and the matching binding non-empty. The `type` enum and binding pattern are schema-enforced at the edge (not re-checked here).

type ServiceSpec

type ServiceSpec struct {
	Type ServiceType `json:"type,omitempty"`
	// KV is set when Type == ServiceTypeKV (ADR-0019, F14).
	KV *KVServiceSpec `json:"kv,omitempty"`
	// Blob is set when Type == ServiceTypeBlob (ADR-0021, F23).
	Blob *BlobServiceSpec `json:"blob,omitempty"`
}

ServiceSpec holds the desired state. Behavioral fields owned by F14/F23. ServiceType is an open typed-string discriminator; enumerated values owned by service ADRs.

type ServiceStatus

type ServiceStatus struct {
	Status `json:",inline"`
}

ServiceStatus holds the observed state.

type ServiceType

type ServiceType string

ServiceType is an open typed-string discriminator for service kinds. Enumerated values are defined by the service ADRs (F14, F23).

const (
	// ServiceTypeKV is the key/value service (ADR-0019, F14).
	ServiceTypeKV ServiceType = "kv"
	// ServiceTypeBlob is the blob storage service (ADR-0021, F23).
	ServiceTypeBlob ServiceType = "blob"
)

func (ServiceType) Schema

func (ServiceType) Schema(huma.Registry) *huma.Schema

Schema carries ServiceType's enum constraint into the generated OpenAPI (ADR-0048).

type Site

type Site struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       SiteSpec   `json:"spec"`
	Status     SiteStatus `json:"status,omitempty"`
}

Site is a namespaced, status-bearing static web deliverable (ADR-0139, F103): an immutable bundle materialized into a governed Bucket prefix and exposed at the edge, with its adjacent Bucket and Route declared inline and owned by it. Ready only once the bundle is materialized and its index is present, so a Site is never Ready over an empty prefix.

func (*Site) EffectivePath

func (s *Site) EffectivePath() string

EffectivePath is where the bundle is served (ADR-0140): spec.ingress.path, else "/" when spec.ingress.host is set, else "/site/<metadata.name>". It lives HERE, not in internal/site, because Validate must check it too and api/** cannot import internal/** — one definition, two callers.

func (*Site) GetStatus

func (s *Site) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*Site) GroupVersionKind

func (s *Site) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Site.

func (*Site) Validate

func (s *Site) Validate() error

Validate performs envelope + semantic validation: Image non-empty; Prefix a DNS-1123 label; Index a relative path (no leading '/'); Deletion ∈ {"", retain} — `delete` is Invalid in V1 with an explicit "not implemented" message (the DeletionPolicy enum is shared with Workflow, so the generated OpenAPI still advertises `delete`); spec.bucket.prefixes must not repeat spec.prefix and must have unique names; ingress.path, when set, begins "/" and is "/" or carries no trailing slash, and the RESOLVED path (EffectivePath, derived or explicit) does not collide with an ingress rule — validating only the written field would let a derived collision reach the reconciler as an unmapped store error (ADR-0140); every ingress rule Path begins "/" and is neither "/" nor a duplicate; ingress.public together with ingress.auth.mode == authenticated is Invalid (the ADR-0120 §4 contradiction, caught here so the reconciler never writes a Route the store's Validate refuses). Cross-resource state (does the Bucket exist) is the RECONCILER's (→ NotReady), never Validate.

type SiteBucket

type SiteBucket struct {
	// Name is the Bucket name; a DNS-1123 label.
	Name ObjectName `json:"name"`
	// Deletion is "retain" (default — the Bucket outlives the Site). "delete" is rejected in V1.
	Deletion DeletionPolicy `json:"deletion,omitempty"`
	// Prefixes are additional sub-domains materialized on the Bucket verbatim (owners included). The
	// Site's own Prefix is added implicitly with NO owner and must not be repeated here.
	Prefixes []BucketPrefix `json:"prefixes,omitempty"`
}

SiteBucket declares the target Bucket (the WorkflowKVStore pattern): adopted if present, created if absent; Deletion governs teardown only.

type SiteIngress

type SiteIngress struct {
	// Host is the exact host match on the owned Route; "" matches any host (ADR-0110 requires a
	// non-empty host in an `explicit`-mode namespace).
	Host string `json:"host,omitempty"`
	// Path is the edge path the bundle is served at (ADR-0140). Empty ⇒ "/" when Host is set, else
	// "/site/<metadata.name>" — so several host-less Sites share one listener without colliding. It
	// begins "/" and carries no trailing slash unless it is exactly "/". Mutable: a change re-programs
	// the Route with no re-upload, but the bundle must be BUILT for the new base path (funcd never
	// rewrites served content).
	Path string `json:"path,omitempty"`
	// Public sets static.public on every compiled backend (ADR-0120 §4 precedence preserved).
	Public bool `json:"public,omitempty"`
	// Auth is the edge auth stance copied onto the owned Route; nil ⇒ inherit the namespace default.
	Auth *RouteAuth `json:"auth,omitempty"`
	// Rules are additional bucket prefixes served alongside the app (the data the app fetches). A rule
	// MAY nest under Path (e.g. /bi/data under /bi) — longest-path-first gives the nested rule priority.
	Rules []SiteRule `json:"rules,omitempty"`
}

SiteIngress declares the Site-owned Route. The bundle is served at EffectivePath; Rules add sibling prefixes.

type SiteRule

type SiteRule struct {
	// Path is the edge path; must begin "/" and must not be "/" (that is the bundle's).
	Path string `json:"path"`
	// Bucket names a Bucket in this Site's namespace; "" ⇒ the Site's own Bucket.
	Bucket ObjectName `json:"bucket,omitempty"`
	// Prefix is the Bucket sub-domain served at Path.
	Prefix string `json:"prefix" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
}

SiteRule serves one bucket prefix at an edge path. Never SPA: a miss is 404, not the app shell.

type SiteSpec

type SiteSpec struct {
	// Image is the site bundle OCI ref (oci-layout://<dir>[:<tag>] or a registry ref; a tag or a
	// digest). A tag is resolved to a digest once per spec generation — the author never types one.
	Image string `json:"image"`
	// Bucket declares the Bucket the bundle materializes into: adopted if present, created if absent.
	Bucket SiteBucket `json:"bucket"`
	// Prefix is the Bucket sub-domain rooting the site; objects land under <Prefix>/<digest-slug>/.
	// Immutable after creation (the site-prefix-immutable admission).
	Prefix string `json:"prefix" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
	// Index is the document served for "/" / a directory / (when SPA) a miss. Default "index.html".
	Index string `json:"index,omitempty"`
	// SPA serves Index (200) for an un-matched path under the bundle rule so a client-side router owns
	// routing. It NEVER applies to a data mount (Ingress.Rules), whose miss is always 404.
	SPA bool `json:"spa,omitempty"`
	// Ingress declares the Site-owned Route (named after the Site). Required in V1.
	Ingress SiteIngress `json:"ingress"`
}

SiteSpec is the desired state: which bundle, where it materializes, and how it is exposed.

type SiteStatus

type SiteStatus struct {
	Status `json:",inline"`
	// Digest is the manifest digest the owned Route currently serves.
	Digest string `json:"digest,omitempty" pattern:"^sha256:[a-f0-9]{64}$"`
	// ServingPrefix is the digest-scoped key prefix the owned Route is programmed with.
	ServingPrefix string `json:"servingPrefix,omitempty"`
	// Objects and Bytes are the materialized bundle's observed size.
	Objects int   `json:"objects,omitempty"`
	Bytes   int64 `json:"bytes,omitempty"`
}

SiteStatus is the observed state: which build is live and where it is served from. Every field is DERIVED on each reconcile — Digest/ServingPrefix from the owned Route's bundle rule (what is actually served) — never read back as durable: the store is last-writer-wins on status and an apply wipes it. Status.ObservedGeneration gates tag resolution (ADR-0139 Decision §2).

type StaticBackend

type StaticBackend struct {
	// Bucket is the Bucket in THIS Route's namespace whose objects are served (binding-as-grant:
	// the Route reads only this declared Bucket; the reconciler validates it exists → BucketNotFound).
	Bucket ObjectName `json:"bucket"`
	// Prefix is the key prefix within the Bucket that roots the site; it ends with "/" (e.g. "bi/") so it
	// never also matches a sibling prefix; "" ⇒ the bucket root.
	Prefix string `json:"prefix,omitempty"`
	// Index is the document served for "/" / a directory / (when SPA) a miss. Default "index.html".
	Index string `json:"index,omitempty"`
	// SPA, when true, serves Index (200) for any un-matched path so a client-side router owns routing;
	// when false, an un-matched path is 404.
	SPA bool `json:"spa,omitempty"`
	// Public, when true, serves this Route openly (stance relaxed to `open`, ADR-0113) when the
	// resolved stance is unset/default — a declared public site. It NEVER overrides an explicit
	// `authenticated` stance (that combination is rejected at admission). Default false ⇒ inherit.
	Public bool `json:"public,omitempty"`
}

StaticBackend serves a Bucket prefix as a static site (ADR-0120, F82): index resolution, content-types, a weak (ModTime,Size) ETag + conditional GET, HTTP Range, an optional SPA fallback, and a pinned three-tier Cache-Control — served through the FEAT-0006 edge with no function code. The bytes are the same per-namespace Bucket view the S3 frontend serves (ADR-0080).

type Status

type Status struct {
	Phase              Phase      `json:"phase,omitempty"`
	ObservedGeneration int64      `json:"observedGeneration,omitempty"`
	Conditions         Conditions `json:"conditions,omitempty"`
}

Status is the shared status base embedded by kinds with observed state. Pure-data/policy kinds (ConfigMap, Secret, Grant, EgressPolicy) do not have status.

type StatusObject

type StatusObject interface {
	Object
	GetStatus() *Status
}

StatusObject is the optional extension implemented by kinds with observed state, giving the controller a generic status write-back seam. ConfigMap, Secret, Grant, and EgressPolicy do NOT implement it.

type StepPhase

type StepPhase string

StepPhase is a step's execution phase within a run.

const (
	StepPending   StepPhase = "Pending"
	StepRunning   StepPhase = "Running"
	StepSucceeded StepPhase = "Succeeded"
	StepFailed    StepPhase = "Failed"
	StepSkipped   StepPhase = "Skipped"
	StepCancelled StepPhase = "Cancelled"
)

func (StepPhase) Schema

func (StepPhase) Schema(huma.Registry) *huma.Schema

Schema carries StepPhase's enum into the generated OpenAPI (ADR-0048).

type StepRetry

type StepRetry struct {
	MaxAttempts int           `json:"maxAttempts,omitempty" minimum:"1" maximum:"100"`
	Backoff     time.Duration `json:"backoff,omitempty" minimum:"0" maximum:"3600000000000"`
}

StepRetry is a per-step retry policy: attempts and exponential backoff.

type StepWhen

type StepWhen struct {
	Condition string `json:"condition"`
}

StepWhen holds a native-JS boolean condition (ADR-0095 Condition mode) evaluated against direct-parent outputs and the run input.

type Tags

type Tags map[string]string

Tags is an optional free-form set of key-value labels on a resource. map[string]string is allowed under ADR-0002: the any-ban targets interface{}/any/map[string]any.

type TimerEvent

type TimerEvent struct {
	Name ObjectName `json:"name"`
	// Interval is the tick period in int64 nanoseconds, bounded 100ms ≤ ≤ 24h (ADR-0023): the floor bars a
	// μs/ns fire-storm, the ceiling bars an unbounded one. The tag literals are the sole schema source; the
	// bounds are re-checked in Validate (which also runs at store.Create, bypassing the huma edge).
	Interval time.Duration `json:"interval" minimum:"100000000" maximum:"86400000000000"` // 100ms–24h
}

TimerEvent is one named timer event: a DNS-1123 name + its own interval. Each fires independently and publishes a named CloudEvent (source=<eventsource> URI, type=<name>).

type TimerSource

type TimerSource struct {
	Events []TimerEvent `json:"events"` // ≥1; unique names
}

TimerSource hosts the timer kind's named events (ADR-0108).

type TypeMeta

type TypeMeta struct {
	APIVersion string `json:"apiVersion"`
	Kind       Kind   `json:"kind"`
}

TypeMeta carries the wire identity of a resource.

type UID

type UID string

UID is a server-assigned opaque unique identifier.

type WorkerNode

type WorkerNode struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Status     WorkerNodeStatus `json:"status,omitempty"`
}

WorkerNode is a cluster-scoped resource representing a compute node. Status-bearing. Behavioral fields (capacity, heartbeat) owned by multi-node ADR.

func (*WorkerNode) GetStatus

func (w *WorkerNode) GetStatus() *Status

GetStatus returns the shared Status pointer, implementing StatusObject.

func (*WorkerNode) GroupVersionKind

func (w *WorkerNode) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for WorkerNode.

func (*WorkerNode) Validate

func (w *WorkerNode) Validate() error

Validate performs envelope validation via the shared validateMeta helper.

type WorkerNodeStatus

type WorkerNodeStatus struct {
	Status `json:",inline"`
}

WorkerNodeStatus holds the observed state.

type Workflow

type Workflow struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       WorkflowSpec   `json:"spec"`
	Status     WorkflowStatus `json:"status,omitempty"`
}

Workflow is a namespaced, status-bearing resource: a declarative multi-step run definition whose steps are functions (ADR-0094, FEAT-0005/F64). The engine owns and materializes the step Functions; a WorkflowRun is one execution.

func (*Workflow) GetStatus

func (w *Workflow) GetStatus() *Status

GetStatus returns the embedded Status for the controller's write-back seam.

func (*Workflow) GroupVersionKind

func (w *Workflow) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for Workflow.

func (*Workflow) Validate

func (w *Workflow) Validate() error

Validate enforces the Workflow rules JSON Schema can't express (ADR-0094): the step kind-union, unique step names, each image step's <workflow>-<step> Function name fitting a DNS label, dependsOn edge validity + acyclicity, the reserved workflow: kind, the onFailure handler constraints, workflow-owned store owners naming a step, and the declared-contract total-defaults rule. Field-format constraints (durations, retry bounds, enums) are schema-enforced at the edge.

type WorkflowContract

type WorkflowContract struct {
	Dialect string          `json:"dialect,omitempty"`
	Input   json.RawMessage `json:"input,omitempty"`
	Output  json.RawMessage `json:"output,omitempty"`
}

WorkflowContract is a declared or derived I/O contract (ADR-0090 ContractBlob shape).

type WorkflowKVStore

type WorkflowKVStore struct {
	// Name is the store name; a DNS-1123 label.
	Name ObjectName `json:"name"`
	// Deletion is "retain" (default — the store outlives the workflow) or "delete".
	Deletion DeletionPolicy `json:"deletion,omitempty"`
	// Tables are the store's sub-domains; each Owner names a step.
	Tables []KVTable `json:"tables"`
}

WorkflowKVStore declares a workflow-owned KVStore whose table owners name a step.

type WorkflowPooling

type WorkflowPooling struct {
	// Mode is "shared" (default — image steps of the same runtime co-locate in one
	// worker pool, saving memory) or "isolated" (each step runs in its own solo
	// worker / container).
	Mode PoolingMode `json:"mode,omitempty"`
	// Worker names the shared pool when Mode is shared; empty ⇒ the workflow's name.
	// Steps of different runtimes never share a worker (the pool is per-runtime); this
	// is the logical pool name they group under.
	Worker string `json:"worker,omitempty" pattern:"^[a-z0-9]([a-z0-9-]{0,61}[a-z0-9])?$"`
	// MinReplicas keeps warm workers: 0 scales to zero (cold start on the first step of
	// the pool), ≥1 avoids the cold-start latency.
	MinReplicas int `json:"minReplicas,omitempty" minimum:"0" maximum:"15"`
}

WorkflowPooling governs how a workflow's materialized step Functions are grouped into worker pools and kept warm. It is applied to each owned Function at materialization (a step's own Pooling overrides it).

type WorkflowRef

type WorkflowRef struct {
	Ref ObjectName `json:"ref,omitempty"`
}

WorkflowRef references a child Workflow by name — a sub-workflow step (F70/ADR-0099).

type WorkflowRun

type WorkflowRun struct {
	TypeMeta   `json:",inline"`
	ObjectMeta `json:"metadata"`
	Spec       WorkflowRunSpec   `json:"spec"`
	Status     WorkflowRunStatus `json:"status,omitempty"`
}

WorkflowRun is a namespaced, status-bearing resource: one execution of a Workflow (ADR-0094, FEAT-0005/F64). Minted by `funcdctl workflow run`, a hand-applied manifest, or (later) a Sensor. The engine drives it to a terminal phase.

func (*WorkflowRun) GetStatus

func (r *WorkflowRun) GetStatus() *Status

GetStatus returns the embedded Status for the controller's write-back seam. Its Phase is unused: the run phase is WorkflowRunStatus.Phase, which shadows it.

func (*WorkflowRun) GroupVersionKind

func (r *WorkflowRun) GroupVersionKind() GroupVersionKind

GroupVersionKind returns the constant GVK for WorkflowRun.

func (*WorkflowRun) Validate

func (r *WorkflowRun) Validate() error

Validate enforces the WorkflowRunSpec rules JSON Schema can't express (ADR-0094): the target workflow is named. Input-vs-contract validation is admission's job (it needs the cached contract), not a field rule.

type WorkflowRunLinks struct {
	Active    []ObjectName `json:"active,omitempty"`
	Succeeded int          `json:"succeeded,omitempty"`
	Failed    int          `json:"failed,omitempty"`
	Cancelled int          `json:"cancelled,omitempty"`
}

WorkflowRunLinks links a Workflow to its runs: active (in-flight) names + lifetime terminal-phase counts. Bounded (active-only); history lives in engine state.

type WorkflowRunSpec

type WorkflowRunSpec struct {
	// Workflow names the Workflow in this run's namespace.
	Workflow ObjectName `json:"workflow"`
	// Input is the run input (validated against the workflow's cached contract at
	// admission); control-plane metadata, size-bounded by the engine.
	Input json.RawMessage `json:"input,omitempty"`
	// Paused requests a graceful pause: no new steps dispatch, in-flight steps finish
	// (set by `funcdctl workflow pause`, cleared by `resume`). Ignored once the run is already
	// terminal: the run keeps its phase.
	Paused bool `json:"paused,omitempty"`
	// Cancel requests cancellation (ADR-0094, ADR-0146): a declarative one-way intent, the same shape
	// as Paused. Set by `funcdctl workflow cancel`, it is observed by the run reconciler on
	// the controller workqueue (never a synchronous endpoint), which closes the in-flight step calls
	// (their late results are discarded), dispatches nothing more, runs no onFailure and terminates
	// the run Cancelled. Ignored once the run is already terminal.
	Cancel bool `json:"cancel,omitempty"`
	// Replay seeds this run from a finished source run's checkpoint (ADR-0107): the engine copies the
	// source's pinned spec/contract/input + the terminal steps outside the replay set, then re-runs
	// `from` + its descendants. When set, Input must be empty (the input comes from the source).
	Replay *ReplaySeed `json:"replay,omitempty"`
}

WorkflowRunSpec is the desired state: which Workflow, the run input, and the declarative pause flag.

type WorkflowRunStatus

type WorkflowRunStatus struct {
	Status `json:",inline"`
	// Phase shadows the embedded Status.Phase: a run has its own phases (ADR-0094), not the resource ones.
	Phase RunPhase        `json:"phase,omitempty"`
	Steps []RunStepStatus `json:"steps,omitempty"`
	// TraceID is the run's W3C trace (ADR-0102), mirrored from the engine record (ADR-0100) so
	// `describe` shows it and `funcdctl workflow logs <run>` (ADR-0106) resolves a run to its logs.
	TraceID string `json:"traceId,omitempty"` // 32 lowercase hex; empty ⇒ a legacy/traceless run
	// Pins binds the run to the step Function revisions it started with (ADR-0190): written before the run starts,
	// they hold those revisions while the run is not terminal.
	Pins []RevisionPin `json:"pins,omitempty"`
	// WorkflowUID is the Workflow's UID at start (ADR-0190 Decision 10); empty for a run started before ADR-0190.
	WorkflowUID UID `json:"workflowUID,omitempty"`
}

WorkflowRunStatus is the coarse mirror of engine run state (Badger is the truth): the run phase plus per-step summaries.

type WorkflowSpec

type WorkflowSpec struct {
	// Steps are the workflow's steps. List order chains implicitly (no dependsOn ⇒
	// the previous step); dependsOn declares explicit edges.
	Steps []WorkflowStep `json:"steps"`
	// KV declares workflow-owned KVStores whose table owners name a step (materialized
	// to the owning Function). Empty ⇒ no owned stores.
	KV []WorkflowKVStore `json:"kv,omitempty"`
	// Contract is the optional declared I/O contract (ADR-0090 shape); nil ⇒ the
	// effective contract is derived (F65). Every optional property must carry a
	// default (the total-defaults rule).
	Contract *WorkflowContract `json:"contract,omitempty"`
	// Timeout is the wall-clock bound on a whole run (paused time excluded); 0 ⇒ none.
	Timeout time.Duration `json:"timeout,omitempty" minimum:"0" maximum:"604800000000000"`
	// OnFailure names a handler function step (defined in Steps, excluded from the DAG)
	// invoked once when the run ends Failed. Empty ⇒ no handler.
	OnFailure ObjectName `json:"onFailure,omitempty"`
	// Pooling configures how the workflow's materialized step Functions are pooled and
	// kept warm (ADR-0046 worker pooling + ADR-0016 scaling). Empty ⇒ the default: all
	// image steps share one pool. A step may override it with its own step.pooling.
	Pooling WorkflowPooling `json:"pooling,omitempty"`
}

WorkflowSpec is the desired state: the ordered steps, workflow-owned KV stores, an optional declared I/O contract, a run-level timeout, and an optional onFailure handler step.

func (WorkflowSpec) EffectiveDependsOn added in v0.2.1

func (s WorkflowSpec) EffectiveDependsOn() map[ObjectName][]ObjectName

EffectiveDependsOn returns each step's parents as the engine schedules them (ADR-0094 Control flow): its dependsOn, else the previous step in list order. The onFailure handler is outside the DAG: it gets no implicit parent and is never the previous step.

type WorkflowStatus

type WorkflowStatus struct {
	Status   `json:",inline"`
	Contract *WorkflowContract    `json:"contract,omitempty"`
	Steps    []WorkflowStepStatus `json:"steps,omitempty"`
	Runs     *WorkflowRunLinks    `json:"runs,omitempty"`
}

WorkflowStatus is the observed state: phase, the effective contract, the resolved step graph (F65 fills it), and the run link (CronJob status.active pattern).

type WorkflowStep

type WorkflowStep struct {
	// Name is the step's name; a DNS-1123 label, unique within the workflow.
	Name ObjectName `json:"name"`
	// Function is a dispatched step: an owned image (materialized) or a ref to an existing Function.
	Function *FunctionStep `json:"function,omitempty"`
	// Builtin is an engine-native step (wait / pass) — run in-process, never dispatched.
	Builtin *BuiltinStep `json:"builtin,omitempty"`
	// Workflow runs a child Workflow as a step (a sub-workflow, F70/ADR-0099).
	Workflow *WorkflowRef `json:"workflow,omitempty"`
	// DependsOn names the parent steps; empty ⇒ follows the previous step in list order.
	DependsOn []ObjectName `json:"dependsOn,omitempty"`
	// Join is the fan-in mode: "all" (default) requires every parent Succeeded, "any"
	// requires one (exclusive-branch merges).
	Join JoinMode `json:"join,omitempty"`
	// When is an optional gate condition (ADR-0095 native-JS boolean); false ⇒ Skipped.
	When *StepWhen `json:"when,omitempty"`
	// Params is a static overlay merged over the step's flowing input (static wins). For a function
	// step it overlays the dispatched input; a pass expression sees the overlaid input; a wait
	// ignores it (output = input verbatim). The onFailure handler takes none (FailureContext only).
	Params json.RawMessage `json:"params,omitempty"`
}

WorkflowStep is one step — a kind-keyed union of exactly one of Function / Builtin / Workflow (Workflow runs a child workflow, F70), plus the orchestration fields common to every kind (ADR-0096).

type WorkflowStepStatus

type WorkflowStepStatus struct {
	Name     ObjectName        `json:"name"`
	Image    string            `json:"image,omitempty"`
	Contract *WorkflowContract `json:"contract,omitempty"`
}

WorkflowStepStatus is one step's resolved digest-pinned image + cached contract.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL