The deciding parts built with this seat list judge the running nats and gitea before their new builds are delivered; a required verb they do not serve yet would refuse them as the seats' holders (mesh-host's composition and the grants part's last-holder rule, read in their suites). The mark goes once every holder serves the verbs. Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
269 lines
6.5 KiB
JSON
269 lines
6.5 KiB
JSON
{
|
|
"format": 1,
|
|
"seat": "container-image-registry",
|
|
"scope": "mesh",
|
|
"grain": "whole",
|
|
"decision": "novox/hq ADR 0605",
|
|
"description": "The mesh's container images, in the one artifact store: the OCI distribution protocol's read side, an image's tags and mirroring an outside image.",
|
|
"delivers": "artifact-store",
|
|
"includes": [
|
|
"registry"
|
|
],
|
|
"verbs": [
|
|
{
|
|
"name": "mirror",
|
|
"description": "Copy an outside image into the store by its pinned digest; emits published or refused.",
|
|
"callers": "mesh-build-image's holder of the image build seat",
|
|
"input": {
|
|
"type": "object",
|
|
"properties": {
|
|
"source": {
|
|
"type": "string",
|
|
"description": "the outside image's reference"
|
|
},
|
|
"digest": {
|
|
"type": "string",
|
|
"description": "its pinned digest, sha256:<hex>"
|
|
},
|
|
"name": {
|
|
"type": "string",
|
|
"description": "the name it is kept under"
|
|
}
|
|
},
|
|
"required": [
|
|
"source",
|
|
"digest",
|
|
"name"
|
|
]
|
|
},
|
|
"answer": {
|
|
"type": "object",
|
|
"properties": {
|
|
"reference": {
|
|
"type": "string",
|
|
"description": "the reference the seat answers"
|
|
},
|
|
"digest": {
|
|
"type": "string",
|
|
"description": "the digest stored"
|
|
}
|
|
},
|
|
"required": [
|
|
"reference",
|
|
"digest"
|
|
]
|
|
},
|
|
"optional": true
|
|
},
|
|
{
|
|
"name": "tags",
|
|
"description": "The tags of one image and the digest each names.",
|
|
"callers": "any caller whose role grants it",
|
|
"input": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "the image"
|
|
}
|
|
},
|
|
"required": [
|
|
"name"
|
|
]
|
|
},
|
|
"answer": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "the image"
|
|
},
|
|
"tags": {
|
|
"type": "array",
|
|
"items": {
|
|
"type": "object",
|
|
"properties": {
|
|
"tag": {
|
|
"type": "string",
|
|
"description": "the tag"
|
|
},
|
|
"digest": {
|
|
"type": "string",
|
|
"description": "its digest"
|
|
}
|
|
},
|
|
"required": [
|
|
"tag",
|
|
"digest"
|
|
]
|
|
},
|
|
"description": "every tag"
|
|
}
|
|
},
|
|
"required": [
|
|
"name",
|
|
"tags"
|
|
]
|
|
},
|
|
"optional": true
|
|
},
|
|
{
|
|
"name": "hold",
|
|
"description": "Keep one untagged bundle, archive or copied base from removal by retention, as the artifact sweep's rules keep it (ADR 0617 §2); never an image of the holder's own. Emits held.",
|
|
"callers": "the module that runs the artifact sweep alone",
|
|
"input": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "the name"
|
|
},
|
|
"digest": {
|
|
"type": "string",
|
|
"description": "the digest"
|
|
},
|
|
"reason": {
|
|
"type": "string",
|
|
"description": "which of the sweep's rules keeps it"
|
|
}
|
|
},
|
|
"required": [
|
|
"name",
|
|
"digest",
|
|
"reason"
|
|
]
|
|
},
|
|
"answer": {
|
|
"type": "object",
|
|
"properties": {
|
|
"held": {
|
|
"type": "boolean",
|
|
"description": "it is held"
|
|
},
|
|
"since": {
|
|
"type": "string",
|
|
"description": "when the hold began, RFC 3339"
|
|
}
|
|
},
|
|
"required": [
|
|
"held"
|
|
]
|
|
},
|
|
"optional": true
|
|
},
|
|
{
|
|
"name": "release",
|
|
"description": "Let a hold go; emits released. By hand only through the holder's own tool, the operator's session as the proved caller, recorded as a hand act.",
|
|
"callers": "the module that runs the artifact sweep; the operator's session through the holder's tool",
|
|
"input": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "the name"
|
|
},
|
|
"digest": {
|
|
"type": "string",
|
|
"description": "the digest"
|
|
},
|
|
"reason": {
|
|
"type": "string",
|
|
"description": "why it is let go"
|
|
}
|
|
},
|
|
"required": [
|
|
"name",
|
|
"digest",
|
|
"reason"
|
|
]
|
|
},
|
|
"answer": {
|
|
"type": "object",
|
|
"properties": {
|
|
"released": {
|
|
"type": "boolean",
|
|
"description": "the hold is gone"
|
|
}
|
|
},
|
|
"required": [
|
|
"released"
|
|
]
|
|
},
|
|
"optional": true
|
|
}
|
|
],
|
|
"events": [
|
|
{
|
|
"name": "held",
|
|
"body": {
|
|
"$ref": "#/defs/Hold"
|
|
}
|
|
},
|
|
{
|
|
"name": "released",
|
|
"body": {
|
|
"$ref": "#/defs/Hold"
|
|
}
|
|
}
|
|
],
|
|
"family": {
|
|
"name": "container-image-registry.events",
|
|
"max-age-days": 7
|
|
},
|
|
"provisions": [
|
|
{
|
|
"name": "artifact-store",
|
|
"form": {
|
|
"type": "object",
|
|
"properties": {
|
|
"url": {
|
|
"type": "string",
|
|
"description": "the store's address"
|
|
}
|
|
},
|
|
"required": [
|
|
"url"
|
|
],
|
|
"description": "the artifact store's read side, the OCI distribution protocol's GET and HEAD, open on the mesh network (design 51)"
|
|
}
|
|
}
|
|
],
|
|
"defs": {
|
|
"Hold": {
|
|
"type": "object",
|
|
"properties": {
|
|
"name": {
|
|
"type": "string",
|
|
"description": "the name"
|
|
},
|
|
"digest": {
|
|
"type": "string",
|
|
"description": "the digest"
|
|
},
|
|
"reason": {
|
|
"type": "string",
|
|
"description": "why"
|
|
},
|
|
"holder": {
|
|
"type": "string",
|
|
"description": "the module holding the seat"
|
|
},
|
|
"by": {
|
|
"type": "string",
|
|
"description": "the caller the holder proved"
|
|
},
|
|
"at": {
|
|
"type": "string",
|
|
"description": "when, RFC 3339"
|
|
}
|
|
},
|
|
"required": [
|
|
"name",
|
|
"digest",
|
|
"holder"
|
|
],
|
|
"description": "the body of held and released"
|
|
}
|
|
}
|
|
}
|