quorate/docs/spec/project-delivery-spec.md

14 KiB

Project Delivery Specification

Project delivery reconciles Forgejo source into published artifacts. A ProjectDelivery declares the desired result, a controller resolves continuous refs and accepts declared point revisions, and a cluster-owned Argo WorkflowTemplate defines all execution.

Delivery declaration

flowchart LR
  D[ProjectDelivery]
  C[Delivery controller]
  T[Cluster-owned WorkflowTemplate]
  W[Workflow]
  V[Vault and VSO]
  A[Build cache]
  P[Declared publication targets]

  D --> C
  C -->|template reference and immutable input| W
  T --> W
  V -->|stage-scoped Secrets| W
  W <-->|cache pull, export, and cleanup| A
  W --> P
apiVersion: delivery.quorate.dev/v1alpha1
kind: ProjectDelivery
metadata:
  name: example
spec:
  source:
    repository: https://git.quorate.dev/example/project
    continuous:
      ref: refs/heads/main
      paths: [packages/example]
  targets:
    - kind: QuayOCI
      repository: quorate/project
    - kind: ExternalOCI
      registry: docker.io
      repository: example/project
    - kind: ForgejoRelease
      repository: https://git.quorate.dev/example/project
  workflowTemplateRef:
    name: example-delivery

source contains exactly one delivery mode:

Mode Selector Trigger identity
continuous One complete ref; optional exact paths and positive-duration debounce Commit SHA or selected Git tree
point A non-empty set of full commit SHAs Full commit SHA

continuous.paths contains exact repository-relative file or directory paths. When present, the trigger identity is the selected Git tree state rather than the commit SHA.

Point delivery declares immutable revisions:

source:
  repository: https://git.quorate.dev/example/project
  point:
    revisions:
      - 0123456789abcdef0123456789abcdef01234567
      - 89abcdef0123456789abcdef0123456789abcdef

status.points records point revisions, Workflow identities and phases, and delivery results.

Point revisions are consumed directly without ref enumeration or resolution.

source.repository identifies the Forgejo repository containing the selected source. Its authority is declaration data rather than an admission boundary.

targets is a non-empty set of workflow-defined publication declarations. The controller treats each declaration as opaque JSON and passes it unchanged. The referenced WorkflowTemplate defines and validates the target kinds and fields it supports.

workflowTemplateRef names a WorkflowTemplate in the ProjectDelivery namespace. Admission rejects cross-namespace references and malformed source selectors.

delivery.quorate.dev/retry names an owned terminal Workflow.

Qualification interface

Field Type Default Model binding
spec.qualification Optional object Absent Configured resources form Deliveries
workflowTemplateRef.name Same-namespace WorkflowTemplate name Required Workflow template
mode Qualification!Policies ManualOnly policy[delivery]
interval Duration 0s Interval[delivery]
delivery.quorate.dev/qualify annotation <build-workflow-name>/<request-id> Absent request[delivery]
Workflow interface Value
Input: source-repository, source-ref, source-revision, targets Selected successful build's parameters
Input: delivery-result Selected build's opaque publication result
Model Input(delivery, build) Tuple of those parameters and publication result
Output: qualification-result Workflow-defined result identifying tested source, artifacts, and retained reports
Result interpretation Qualification WorkflowTemplate

Reconciliation and execution

Authority

Artifact Authority
Project Delivery specification Declaration and status schema, Workflow interface, objectives, and security
Project Delivery state model Attempt eligibility and history, controller submission, Argo execution synchronization, persistence, lifecycle, and build concurrency
Qualification state model Qualification eligibility, annotation consumption, input capture, interval, and global execution slot

Build workflow interface

The diagram is the standard ProjectDelivery build workflow DAG shape; deviation from it requires evidence that substantiates the deviation.

flowchart LR
  T[Toolchain pull] --> B[Build]
  C[Cache pull] --> B
  S[Source pull] --> B
  B --> E[Cache export and cleanup]
  B --> P[Publish to declared targets]
Parameter Value
source-repository Declared repository URL
source-ref Complete selected continuous ref, or empty for point delivery
source-revision Resolved full commit SHA
targets Declaration-provided JSON target set

Delivery objectives

Measure delivery elapsed time from Workflow startedAt to terminal finishedAt, excluding intervals when waiting on WAN is the sole active work.

Cache state Requirement
Cold No reusable build state; within 900 seconds.
Warm Reusable build state; within 300 seconds.

The WorkflowTemplate owns the DAG:

Concern Owner
Stages, actions, dependencies, retries Argo WorkflowTemplate
Build and assembly image selection Argo WorkflowTemplate
Action and builder image preparation Cluster
Stage Secret references Argo WorkflowTemplate
Secret material and projection Vault and VSO
Stage egress Kubernetes NetworkPolicy
Continuous source selection and duplicate suppression Delivery controller
Cache creation, invalidation, cleanup, and layout Argo WorkflowTemplate
Cache contract Value
Prefix projects/<project>/<workflow>/cache/<cache>/
Manifest _latest.json
Pull cacheVersion and inputHashes match
Export Replace _latest.json
Cleanup Remove unreferenced payloads during cache export
Controller No cache inspection or enforcement
_latest.json field Type Value
schemaVersion Integer 1
cacheVersion String Workflow cache version
inputHashes Object Repository-relative path to SHA-256 map
payloadKey String objects/<payload-sha256>.tar.zst

Workflow security requirements

Every delivery WorkflowTemplate and its supporting namespace resources meet these requirements:

Boundary Requirement
Ownership Commands, images, target interpretation, Secret references, and pod security are cluster-owned
Supply chain Action and executor images use immutable digests of latest stable releases; deprecated APIs and components are forbidden; source uses the selected full SHA
Runtime gvisor where non-cluster-owned code executes; restricted Pod Security; non-root; RuntimeDefault; no privilege escalation or capabilities; read-only root filesystem
Host No privileged container, host namespace, hostPath, device, or runtime socket
Kubernetes Action containers receive no Kubernetes credential; executor tokens are bound, short-lived, and limited to Workflow task results and artifact GC
Delivery stages A stage is a Pod boundary only when its network, credential, input, or output access differs. Actions with identical access execute in the same Pod.
Network Default deny; each stage permits only executor traffic, artifact handoff, and its declared endpoints
Credentials Vault to VSO to one read-only stage mount; never parameters, environment, commands, logs, or artifacts
Handoff Stages exchange state through the Workflow PVC; publishers transfer immutable output
Cache Cache reads and writes use stage-scoped credentials
Ephemeral state One ephemeral PVC is the sole working data plane for the build Workflow lifetime
Build interface Repository supplies source only; OCI delivery uses cluster-owned apko configuration
Resources CPU requests, memory requests, and memory limits on every pod

Publication credentials are destination-native, restricted to the declared destination, and mounted only in the publication stage.

Project-delivery credentials are never shared with Smeltery.

Scope

Delivery succeeds when every declared target reports successful publication of the Workflow's immutable output.

Included Excluded
Source-ref observation and immutable revision selection Repository visibility
Duplicate suppression and Workflow creation Vulnerability policy and scan gating
Project-specific build, test, assembly, and publication DAGs Candidate repositories and promotion
Manual and interval-controlled qualification of published artifacts Deployment approval and rollout gating
Publication digests, checksums, URLs, and Workflow status Deployment and Flux manifest changes
Stage isolation, credentials, and network policy Per-repository publisher identities and grants; published artifact retention and registry garbage collection