B5g3-2: the mesh-catalog seat's input verb answers in chunks

Builds: design 47 G §712, §354, §681, A-237, A-139

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 09:14:28 +01:00
parent b7e251a463
commit ccbefc5653
5 changed files with 37 additions and 24 deletions
@@ -1379,16 +1379,18 @@ type OutdatedAnswer struct {
// InputInput is what input takes.
type InputInput struct {
// 128 random bits the caller chooses: the subject token of this send's chunks and acknowledgements
Call string `json:"call"`
// the input's sha256
Digest string `json:"digest"`
}
// InputAnswer is what input answers.
type InputAnswer struct {
// how many chunks are sent; 0 when there is no input of that digest
Chunks int64 `json:"chunks"`
// the input's sha256
Digest string `json:"digest"`
// the input's exact bytes, base64
Input string `json:"input"`
}
// EntryInput is what entry takes.
@@ -171,9 +171,9 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v OutdatedInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "outdated answers an entry behind", subject: "", given: "{\"behind\":[{\"act\":\"rebuild\",\"dependency\":{\"artifact\":\"mesh-sdk:go\",\"branch\":\"main\",\"source\":3589},\"kind\":1,\"module\":\"nats\",\"newest\":\"0.1.15 sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"recorded\":\"0.1.14 sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"version\":\"1.2.3\"}]}", wire: "{\"behind\":[{\"act\":\"rebuild\",\"dependency\":{\"artifact\":\"mesh-sdk:go\",\"branch\":\"main\",\"source\":3589},\"kind\":1,\"module\":\"nats\",\"newest\":\"0.1.15 sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"recorded\":\"0.1.14 sha256:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"version\":\"1.2.3\"}]}",
decode: func(b []byte) (any, error) { var v OutdatedAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "input asks a step's input by digest", subject: "", given: "{\"digest\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"}", wire: "{\"digest\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"}",
{name: "input asks a step's input by digest", subject: "", given: "{\"call\":\"0123456789abcdef0123456789abcdef\",\"digest\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"}", wire: "{\"call\":\"0123456789abcdef0123456789abcdef\",\"digest\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"}",
decode: func(b []byte) (any, error) { var v InputInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "input answers the exact bytes", subject: "", given: "{\"digest\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"input\":\"eyJ2IjoxfQ==\"}", wire: "{\"digest\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\",\"input\":\"eyJ2IjoxfQ==\"}",
{name: "input answers how many chunks carry the exact bytes", subject: "", given: "{\"chunks\":3,\"digest\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"}", wire: "{\"chunks\":3,\"digest\":\"0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"}",
decode: func(b []byte) (any, error) { var v InputAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "entry asks by fingerprint", subject: "", given: "{\"fingerprint\":\"src2:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"}", wire: "{\"fingerprint\":\"src2:0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef\"}",
decode: func(b []byte) (any, error) { var v EntryInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
@@ -424,15 +424,16 @@
"name": "input asks a step's input by digest",
"of": "verb:input.input",
"given": {
"call": "0123456789abcdef0123456789abcdef",
"digest": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}
},
{
"name": "input answers the exact bytes",
"name": "input answers how many chunks carry the exact bytes",
"of": "verb:input.answer",
"given": {
"digest": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"input": "eyJ2IjoxfQ=="
"chunks": 3,
"digest": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}
},
{
@@ -171,7 +171,7 @@
},
{
"name": "seat-definitions",
"description": "The seat list (ADR 0636 \u00a74): with no seat, every trunk seat with its digest and the revision of the list; with a seat, that trunk definition resolved with the parts it includes. Reads only.",
"description": "The seat list (ADR 0636 §4): with no seat, every trunk seat with its digest and the revision of the list; with a seat, that trunk definition resolved with the parts it includes. Reads only.",
"input": {
"properties": {
"seat": {
@@ -250,7 +250,7 @@
},
{
"name": "revision",
"description": "The catalog half of the revision view (ADR 0656 \u00a76): one catalog graph revision with its entries whole, the trunk heads, the seat definitions by digest, and each manifest's verdict and fingerprint; the trunk's newest when no revision and no candidate is named, or a candidate's for its group and heads. Answered by the holder from what it holds, in its own runtime (ADR 0663), in pages of entries. Reads only. A watched branch with no revision yet answers {none-yet: true} alone (design 47 G section 530).",
"description": "The catalog half of the revision view (ADR 0656 §6): one catalog graph revision with its entries whole, the trunk heads, the seat definitions by digest, and each manifest's verdict and fingerprint; the trunk's newest when no revision and no candidate is named, or a candidate's for its group and heads. Answered by the holder from what it holds, in its own runtime (ADR 0663), in pages of entries. Reads only. A watched branch with no revision yet answers {none-yet: true} alone (design 47 G section 530).",
"input": {
"type": "object",
"properties": {
@@ -554,17 +554,23 @@
"seat:node-build-node",
"seat:node-build-image"
],
"description": "A step's input by its digest, as the indexer keeps it for a validation step it asked a build seat to run (design 47 G section 354).",
"description": "A step's input by its digest, as the indexer keeps it for a validation step it asked a build seat to run (design 47 G section 354): its fields, then the bytes in chunks of at most 512 KiB on the chunk subject of the call, each acknowledged by the caller on the ack subject within 30 seconds; the input is of any size.",
"input": {
"type": "object",
"properties": {
"digest": {
"type": "string",
"description": "the input's sha256"
},
"call": {
"type": "string",
"description": "128 random bits the caller chooses: the subject token of this send's chunks and acknowledgements",
"minLength": 1
}
},
"required": [
"digest"
"digest",
"call"
]
},
"answer": {
@@ -574,16 +580,18 @@
"type": "string",
"description": "the input's sha256"
},
"input": {
"type": "string",
"description": "the input's exact bytes, base64"
"chunks": {
"type": "integer",
"minimum": 0,
"description": "how many chunks are sent; 0 when there is no input of that digest"
}
},
"required": [
"digest",
"input"
"chunks"
]
}
},
"chunks": true
},
{
"name": "entry",
@@ -614,7 +622,7 @@
}
}
],
"description": "The catalog of the mesh: every module the trunk holds with its manifest, fingerprint and verdict, the packages published, and the seat list (ADR 0636 \u00a71, \u00a74).",
"description": "The catalog of the mesh: every module the trunk holds with its manifest, fingerprint and verdict, the packages published, and the seat list (ADR 0636 §1, §4).",
"family": {
"name": "mesh-catalog.events",
"max-age-days": 7
@@ -1793,7 +1801,7 @@
"name": "inputs",
"template": "state",
"history": 1,
"description": "a step's input, named by its write time and its sha256 (design 47 G section 354)",
"description": "a step's input, named by its write time and its sha256; a value over one chunk is held in the state's objects store (design 47 G sections 354, 712)",
"key-forms": [
{
"key": "<time>.<digest>",
@@ -1918,7 +1926,7 @@
"additionalProperties": {
"$ref": "#/defs/BuildEdge"
},
"description": "its build edges, by language (ADR 0603 \u00a72)"
"description": "its build edges, by language (ADR 0603 §2)"
},
"provides": {
"type": "array",
@@ -1958,14 +1966,14 @@
"items": {
"type": "string"
},
"description": "its verb edges left out because they lie on a cycle (ADR 0614 \u00a73)"
"description": "its verb edges left out because they lie on a cycle (ADR 0614 §3)"
},
"needs": {
"type": "array",
"items": {
"type": "string"
},
"description": "the manifest reads a node-engine must state to compose it, its templates' forms included, as the forge bridge read them at the merge (ADR 0614 \u00a74, ADR 0632 \u00a72)"
"description": "the manifest reads a node-engine must state to compose it, its templates' forms included, as the forge bridge read them at the merge (ADR 0614 §4, ADR 0632 §2)"
},
"main": {
"type": "string",
@@ -2256,7 +2264,7 @@
},
"BuildEdge": {
"type": "object",
"description": "the build edge of one language: the build module that builds the module, and the toolchain and recipe version its fingerprint names (ADR 0603 \u00a72)",
"description": "the build edge of one language: the build module that builds the module, and the toolchain and recipe version its fingerprint names (ADR 0603 §2)",
"properties": {
"module": {
"type": "string",
@@ -829,16 +829,18 @@ export interface OutdatedAnswer {
/** is what input takes. */
export interface InputInput {
/** 128 random bits the caller chooses: the subject token of this send's chunks and acknowledgements */
"call": string;
/** the input's sha256 */
"digest": string;
}
/** is what input answers. */
export interface InputAnswer {
/** how many chunks are sent; 0 when there is no input of that digest */
"chunks": number;
/** the input's sha256 */
"digest": string;
/** the input's exact bytes, base64 */
"input": string;
}
/** is what entry takes. */