ce7cb702218693d08ea6d83464d2457c9250027c

This commit is contained in:
ms2k 2026-11-12 20:46:28 +09:00
commit 34c5f8963c

View file

@ -0,0 +1,201 @@
# 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
```mermaid
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
```
```yaml
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:
```yaml
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](project-delivery/ProjectDelivery.tla) | Attempt eligibility and history, controller submission, Argo execution synchronization, persistence, lifecycle, and build concurrency |
| [Qualification state model](project-delivery/Qualification.tla) | 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.
```mermaid
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 |