The checker's seat serves a checking program's input, a verdict names the program that judged it, and the build step's part carries the run ask (issue 1921, milestone 47/G D1)

B0's run job, its input verb and judged-by move from mesh-sdk's go/delivery
into the Delivery domain's contracts, with B0's JSON names: the part
build-step carries StepAsk.run and the defs RunJob, RunProgram, RunHead,
RunInput and RunAnswer beside compose (the lead's ruling on Q1), and a
step's result the run's exit, output and said.

Claude-Session: https://claude.ai/code/session_01NcbgfFSnn24M3GcqttoU7i
This commit is contained in:
2026-11-07 02:27:44 +01:00
parent c3d47e4733
commit ea0b6a075b
18 changed files with 794 additions and 26 deletions
@@ -17,11 +17,12 @@ const (
VerbTry = "try"
VerbTryRead = "try-read"
VerbTryEnd = "try-end"
VerbInput = "input"
)
// Verbs is every verb the seat serves, in its definition's order: a new copy each call.
func Verbs() []string {
return []string{VerbTry, VerbTryRead, VerbTryEnd}
return []string{VerbTry, VerbTryRead, VerbTryEnd, VerbInput}
}
// The holder's own events, listed beside the seat and published under the holder's subjects (ADR 0620 §2).
@@ -273,6 +274,20 @@ type TryEndAnswer struct {
ID string `json:"id"`
}
// InputInput is what input takes.
type InputInput struct {
// the input's sha256, 64 lowercase hex digits, as the run ask names it
Digest string `json:"digest"`
}
// InputAnswer is what input answers.
type InputAnswer struct {
// the digest asked
Digest string `json:"digest"`
// the input's exact bytes, base64, so no encoding on the way changes a byte the digest covers
Input string `json:"input"`
}
// VerdictHolderEventSeriesItem is a type of the contract.
type VerdictHolderEventSeriesItem struct {
// its artifact, or the package's ecosystem name as the module's packages name it
@@ -343,6 +358,29 @@ type VerdictsByGroupHeadsValueFailuresItem struct {
Words string `json:"words,omitempty"`
}
// VerdictsByGroupHeadsValueJudgedByHeadsItem is a type of the contract.
type VerdictsByGroupHeadsValueJudgedByHeadsItem struct {
Commit string `json:"commit"`
Repository string `json:"repository"`
}
// VerdictsByGroupHeadsValueJudgedByProgram is a type of the contract.
type VerdictsByGroupHeadsValueJudgedByProgram struct {
Commit string `json:"commit"`
Dir string `json:"dir"`
Package string `json:"package"`
Repository string `json:"repository"`
}
// VerdictsByGroupHeadsValueJudgedBy is the checking program that judged the check: where it was built, the key its build is kept under, whether this check's run built it, and the heads it read (ADR 0644, ADR 0656). Absent in a value written before it.
type VerdictsByGroupHeadsValueJudgedBy struct {
Built bool `json:"built,omitempty"`
Heads []VerdictsByGroupHeadsValueJudgedByHeadsItem `json:"heads"`
// program- and 16 hex digits
Key string `json:"key"`
Program VerdictsByGroupHeadsValueJudgedByProgram `json:"program"`
}
// VerdictsByGroupHeadsValueLevelsValue is a type of the contract.
type VerdictsByGroupHeadsValueLevelsValue struct {
Kept int64 `json:"kept"`
@@ -379,6 +417,8 @@ type VerdictsByGroupHeadsValue struct {
Group string `json:"group"`
// 12 hex digits
Heads string `json:"heads"`
// the checking program that judged the check: where it was built, the key its build is kept under, whether this check's run built it, and the heads it read (ADR 0644, ADR 0656). Absent in a value written before it
JudgedBy *VerdictsByGroupHeadsValueJudgedBy `json:"judged-by,omitempty"`
// by level, unit or integration
Levels map[string]VerdictsByGroupHeadsValueLevelsValue `json:"levels,omitempty"`
Machines []string `json:"machines,omitempty"`
@@ -29,6 +29,12 @@ func TestFixtures(t *testing.T) {
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a pass judged by the checking program built at a mesh-delivery head", subject: "", given: "{\"group\":\"feat/registry\",\"heads\":\"0123456789ab\",\"judged-by\":{\"built\":true,\"heads\":[{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-delivery\"}],\"key\":\"program-0123456789abcdef\",\"program\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"dir\":\"modules/mesh-delivery-checker\",\"package\":\"./cmd/mesh-checking-program\",\"repository\":\"novox/mesh-delivery\"}},\"levels\":{\"integration\":{\"kept\":0,\"run\":3},\"unit\":{\"kept\":0,\"run\":12}},\"state\":\"pass\",\"v\":1}", wire: "{\"group\":\"feat/registry\",\"heads\":\"0123456789ab\",\"judged-by\":{\"built\":true,\"heads\":[{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-delivery\"}],\"key\":\"program-0123456789abcdef\",\"program\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"dir\":\"modules/mesh-delivery-checker\",\"package\":\"./cmd/mesh-checking-program\",\"repository\":\"novox/mesh-delivery\"}},\"levels\":{\"integration\":{\"kept\":0,\"run\":3},\"unit\":{\"kept\":0,\"run\":12}},\"state\":\"pass\",\"v\":1}",
decode: func(b []byte) (any, error) {
var v VerdictsByGroupHeadsValue
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a kept pass", subject: "", given: "{\"at\":\"2026-11-05T10:00:00Z\",\"level\":\"unit\",\"package\":\"go/keys\",\"repository\":\"novox/mesh-sdk\",\"state\":\"pass\",\"tests\":4,\"took\":120,\"toolchain\":\"go1.26\",\"v\":1}", wire: "{\"at\":\"2026-11-05T10:00:00Z\",\"level\":\"unit\",\"package\":\"go/keys\",\"repository\":\"novox/mesh-sdk\",\"state\":\"pass\",\"tests\":4,\"took\":120,\"toolchain\":\"go1.26\",\"v\":1}",
decode: func(b []byte) (any, error) { var v KeptByLevelDigestValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "the status owed for a head", subject: "", given: "{\"act\":\"status=mesh/check\",\"context\":\"mesh/check\",\"state\":\"success\",\"v\":1}", wire: "{\"act\":\"status=mesh/check\",\"context\":\"mesh/check\",\"state\":\"success\",\"v\":1}",
@@ -43,6 +49,10 @@ func TestFixtures(t *testing.T) {
err := json.Unmarshal(b, &v)
return v, err
}, subjectIs: nil},
{name: "a checking program asks its input by its digest", subject: "", given: "{\"digest\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"}", wire: "{\"digest\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\"}",
decode: func(b []byte) (any, error) { var v InputInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "the input answered as its exact bytes, base64", subject: "", given: "{\"digest\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"input\":\"eyJ2IjoxfQ==\"}", wire: "{\"digest\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"input\":\"eyJ2IjoxfQ==\"}",
decode: func(b []byte) (any, error) { var v InputAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
}
for _, c := range cases {
v, err := c.decode([]byte(c.given))
+60 -7
View File
@@ -386,6 +386,51 @@ type Program struct {
Path string `json:"path"`
}
// RunAnswer is what a run ask's step answers: whether this run built the program or took the one kept under its key, the key, the program's exit, the last line of its standard output and the first of its standard error.
type RunAnswer struct {
Built bool `json:"built"`
Exit int64 `json:"exit"`
Key string `json:"key"`
// raw when it is JSON, else a JSON string
Output any `json:"output,omitempty"`
Said string `json:"said,omitempty"`
}
// RunHead is one commit a run's program reads.
type RunHead struct {
Commit string `json:"commit"`
Repository string `json:"repository"`
}
// RunInput is a run's input by reference: the seat verb the asker serves it on (seat:<seat>.<verb>), the sha256 of its bytes and its size, at most 256 KiB.
type RunInput struct {
// 64 lowercase hex digits
Digest string `json:"digest"`
// bytes
Size int64 `json:"size"`
Verb string `json:"verb"`
}
// RunJob is a run ask's job: where its program is built, the heads it reads (each laid read-only at its repository's path), its input by reference, its arguments and what it is for.
type RunJob struct {
// the program's arguments, each a word or a flag
Args []string `json:"args,omitempty"`
// the commits the program reads, a repository at most once
Heads []RunHead `json:"heads"`
Input RunInput `json:"input"`
Program RunProgram `json:"program"`
// what the run is for, for a reader of the ask
Reader string `json:"reader,omitempty"`
}
// RunProgram is where a run's program is built: the repository and full commit fetched, the Go module's directory in it and the program's import path.
type RunProgram struct {
Commit string `json:"commit"`
Dir string `json:"dir"`
Package string `json:"package"`
Repository string `json:"repository"`
}
// Step is one step a build module runs on a node.
type Step struct {
// when (RFC 3339 time)
@@ -460,25 +505,33 @@ type StepAsk struct {
Needs []string `json:"needs,omitempty"`
// package to the tagged version a build pins
Packages map[string]string `json:"packages,omitempty"`
// a run: a program built from a change and run in the build seat's sandbox over the heads, its input asked of a verb of the asker's seat; the Go seat's check stream alone carries it, as a compose
Run *RunJob `json:"run,omitempty"`
// the layout version
V int64 `json:"v,omitempty"`
}
// StepResult is what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the four.
// StepResult is what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a run's built, key, exit, output and said; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the five.
type StepResult struct {
Artifacts []BuiltArtifact `json:"artifacts,omitempty"`
Built bool `json:"built,omitempty"`
// the holder declined the ask: its node lacks what the ask needs
Declined bool `json:"declined,omitempty"`
Fetch *FetchAnswer `json:"fetch,omitempty"`
Imports []string `json:"imports,omitempty"`
Key string `json:"key,omitempty"`
Declined bool `json:"declined,omitempty"`
// a run's program's exit status
Exit int64 `json:"exit,omitempty"`
Fetch *FetchAnswer `json:"fetch,omitempty"`
Imports []string `json:"imports,omitempty"`
Key string `json:"key,omitempty"`
// what the holder's node lacks of it
Lacks []string `json:"lacks,omitempty"`
Levels []LevelAnswer `json:"levels,omitempty"`
// what the declined ask needs
Needs []string `json:"needs,omitempty"`
OutOfStep []string `json:"out-of-step,omitempty"`
Needs []string `json:"needs,omitempty"`
OutOfStep []string `json:"out-of-step,omitempty"`
// a run's program's last line of standard output: raw when it is JSON, else a JSON string
Output any `json:"output,omitempty"`
// a run's program's first line of standard error, or why the step could not run it
Said string `json:"said,omitempty"`
Toolchain *ToolchainUsed `json:"toolchain,omitempty"`
// the compose-candidate verdict (the composer's own layout)
Verdict any `json:"verdict,omitempty"`
@@ -49,6 +49,10 @@ func TestFixtures(t *testing.T) {
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a finished check step whose head does not merge", subject: "", given: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d5\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"conflicts\":[\"a.go\",\"sub/b.go\"],\"modules\":[\".\"],\"workspace\":\"mvii1iwz5050eb\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"c3d5\",\"node\":\"ace\",\"result\":{\"fetch\":{\"base\":\"abcdef0123456789abcdef0123456789abcdef01\",\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"conflicts\":[\"a.go\",\"sub/b.go\"],\"modules\":[\".\"],\"workspace\":\"mvii1iwz5050eb\"}},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"passed\",\"tool\":\"check\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
{name: "a run ask of the checking program over two heads", subject: "mesh.seat.node-build-go.accept.check", given: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"id\":\"r5e6\",\"kind\":\"check\",\"language\":\"go\",\"run\":{\"args\":[\"-verdict\"],\"heads\":[{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-delivery\"},{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-sdk\"}],\"input\":{\"digest\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"size\":7,\"verb\":\"seat:mesh-delivery-checker.input\"},\"program\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"dir\":\"modules/mesh-delivery-checker\",\"package\":\"./cmd/mesh-checking-program\",\"repository\":\"novox/mesh-delivery\"},\"reader\":\"checking program of mesh-delivery head\"},\"v\":1}", wire: "{\"asker\":\"mesh-delivery-checker\",\"at\":\"2026-11-05T10:00:00Z\",\"id\":\"r5e6\",\"kind\":\"check\",\"language\":\"go\",\"run\":{\"args\":[\"-verdict\"],\"heads\":[{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-delivery\"},{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"repository\":\"novox/mesh-sdk\"}],\"input\":{\"digest\":\"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855\",\"size\":7,\"verb\":\"seat:mesh-delivery-checker.input\"},\"program\":{\"commit\":\"0123456789abcdef0123456789abcdef01234567\",\"dir\":\"modules/mesh-delivery-checker\",\"package\":\"./cmd/mesh-checking-program\",\"repository\":\"novox/mesh-delivery\"},\"reader\":\"checking program of mesh-delivery head\"},\"v\":1}",
decode: func(b []byte) (any, error) { var v CheckAccept; err := json.Unmarshal(b, &v); return v, err }, subjectIs: regexp.MustCompile("^mesh\\.seat\\.node-build-go\\.accept\\.check$")},
{name: "a finished run step whose program exited non-zero", subject: "", given: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"r5e6\",\"node\":\"ace\",\"result\":{\"built\":true,\"exit\":2,\"key\":\"program-0123456789abcdef\",\"said\":\"the facts name no head\"},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"failed\",\"tool\":\"check\",\"v\":1}", wire: "{\"ended\":\"2026-11-05T10:01:00Z\",\"id\":\"r5e6\",\"node\":\"ace\",\"result\":{\"built\":true,\"exit\":2,\"key\":\"program-0123456789abcdef\",\"said\":\"the facts name no head\"},\"started\":\"2026-11-05T10:00:00Z\",\"state\":\"failed\",\"tool\":\"check\",\"v\":1}",
decode: func(b []byte) (any, error) { var v StepsByNodeIDValue; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
}
for _, c := range cases {
v, err := c.decode([]byte(c.given))
+60 -7
View File
@@ -386,6 +386,51 @@ type Program struct {
Path string `json:"path"`
}
// RunAnswer is what a run ask's step answers: whether this run built the program or took the one kept under its key, the key, the program's exit, the last line of its standard output and the first of its standard error.
type RunAnswer struct {
Built bool `json:"built"`
Exit int64 `json:"exit"`
Key string `json:"key"`
// raw when it is JSON, else a JSON string
Output any `json:"output,omitempty"`
Said string `json:"said,omitempty"`
}
// RunHead is one commit a run's program reads.
type RunHead struct {
Commit string `json:"commit"`
Repository string `json:"repository"`
}
// RunInput is a run's input by reference: the seat verb the asker serves it on (seat:<seat>.<verb>), the sha256 of its bytes and its size, at most 256 KiB.
type RunInput struct {
// 64 lowercase hex digits
Digest string `json:"digest"`
// bytes
Size int64 `json:"size"`
Verb string `json:"verb"`
}
// RunJob is a run ask's job: where its program is built, the heads it reads (each laid read-only at its repository's path), its input by reference, its arguments and what it is for.
type RunJob struct {
// the program's arguments, each a word or a flag
Args []string `json:"args,omitempty"`
// the commits the program reads, a repository at most once
Heads []RunHead `json:"heads"`
Input RunInput `json:"input"`
Program RunProgram `json:"program"`
// what the run is for, for a reader of the ask
Reader string `json:"reader,omitempty"`
}
// RunProgram is where a run's program is built: the repository and full commit fetched, the Go module's directory in it and the program's import path.
type RunProgram struct {
Commit string `json:"commit"`
Dir string `json:"dir"`
Package string `json:"package"`
Repository string `json:"repository"`
}
// Step is one step a build module runs on a node.
type Step struct {
// when (RFC 3339 time)
@@ -460,25 +505,33 @@ type StepAsk struct {
Needs []string `json:"needs,omitempty"`
// package to the tagged version a build pins
Packages map[string]string `json:"packages,omitempty"`
// a run: a program built from a change and run in the build seat's sandbox over the heads, its input asked of a verb of the asker's seat; the Go seat's check stream alone carries it, as a compose
Run *RunJob `json:"run,omitempty"`
// the layout version
V int64 `json:"v,omitempty"`
}
// StepResult is what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the four.
// StepResult is what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a run's built, key, exit, output and said; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the five.
type StepResult struct {
Artifacts []BuiltArtifact `json:"artifacts,omitempty"`
Built bool `json:"built,omitempty"`
// the holder declined the ask: its node lacks what the ask needs
Declined bool `json:"declined,omitempty"`
Fetch *FetchAnswer `json:"fetch,omitempty"`
Imports []string `json:"imports,omitempty"`
Key string `json:"key,omitempty"`
Declined bool `json:"declined,omitempty"`
// a run's program's exit status
Exit int64 `json:"exit,omitempty"`
Fetch *FetchAnswer `json:"fetch,omitempty"`
Imports []string `json:"imports,omitempty"`
Key string `json:"key,omitempty"`
// what the holder's node lacks of it
Lacks []string `json:"lacks,omitempty"`
Levels []LevelAnswer `json:"levels,omitempty"`
// what the declined ask needs
Needs []string `json:"needs,omitempty"`
OutOfStep []string `json:"out-of-step,omitempty"`
Needs []string `json:"needs,omitempty"`
OutOfStep []string `json:"out-of-step,omitempty"`
// a run's program's last line of standard output: raw when it is JSON, else a JSON string
Output any `json:"output,omitempty"`
// a run's program's first line of standard error, or why the step could not run it
Said string `json:"said,omitempty"`
Toolchain *ToolchainUsed `json:"toolchain,omitempty"`
// the compose-candidate verdict (the composer's own layout)
Verdict any `json:"verdict,omitempty"`
+60 -7
View File
@@ -386,6 +386,51 @@ type Program struct {
Path string `json:"path"`
}
// RunAnswer is what a run ask's step answers: whether this run built the program or took the one kept under its key, the key, the program's exit, the last line of its standard output and the first of its standard error.
type RunAnswer struct {
Built bool `json:"built"`
Exit int64 `json:"exit"`
Key string `json:"key"`
// raw when it is JSON, else a JSON string
Output any `json:"output,omitempty"`
Said string `json:"said,omitempty"`
}
// RunHead is one commit a run's program reads.
type RunHead struct {
Commit string `json:"commit"`
Repository string `json:"repository"`
}
// RunInput is a run's input by reference: the seat verb the asker serves it on (seat:<seat>.<verb>), the sha256 of its bytes and its size, at most 256 KiB.
type RunInput struct {
// 64 lowercase hex digits
Digest string `json:"digest"`
// bytes
Size int64 `json:"size"`
Verb string `json:"verb"`
}
// RunJob is a run ask's job: where its program is built, the heads it reads (each laid read-only at its repository's path), its input by reference, its arguments and what it is for.
type RunJob struct {
// the program's arguments, each a word or a flag
Args []string `json:"args,omitempty"`
// the commits the program reads, a repository at most once
Heads []RunHead `json:"heads"`
Input RunInput `json:"input"`
Program RunProgram `json:"program"`
// what the run is for, for a reader of the ask
Reader string `json:"reader,omitempty"`
}
// RunProgram is where a run's program is built: the repository and full commit fetched, the Go module's directory in it and the program's import path.
type RunProgram struct {
Commit string `json:"commit"`
Dir string `json:"dir"`
Package string `json:"package"`
Repository string `json:"repository"`
}
// Step is one step a build module runs on a node.
type Step struct {
// when (RFC 3339 time)
@@ -460,25 +505,33 @@ type StepAsk struct {
Needs []string `json:"needs,omitempty"`
// package to the tagged version a build pins
Packages map[string]string `json:"packages,omitempty"`
// a run: a program built from a change and run in the build seat's sandbox over the heads, its input asked of a verb of the asker's seat; the Go seat's check stream alone carries it, as a compose
Run *RunJob `json:"run,omitempty"`
// the layout version
V int64 `json:"v,omitempty"`
}
// StepResult is what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the four.
// StepResult is what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a run's built, key, exit, output and said; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the five.
type StepResult struct {
Artifacts []BuiltArtifact `json:"artifacts,omitempty"`
Built bool `json:"built,omitempty"`
// the holder declined the ask: its node lacks what the ask needs
Declined bool `json:"declined,omitempty"`
Fetch *FetchAnswer `json:"fetch,omitempty"`
Imports []string `json:"imports,omitempty"`
Key string `json:"key,omitempty"`
Declined bool `json:"declined,omitempty"`
// a run's program's exit status
Exit int64 `json:"exit,omitempty"`
Fetch *FetchAnswer `json:"fetch,omitempty"`
Imports []string `json:"imports,omitempty"`
Key string `json:"key,omitempty"`
// what the holder's node lacks of it
Lacks []string `json:"lacks,omitempty"`
Levels []LevelAnswer `json:"levels,omitempty"`
// what the declined ask needs
Needs []string `json:"needs,omitempty"`
OutOfStep []string `json:"out-of-step,omitempty"`
Needs []string `json:"needs,omitempty"`
OutOfStep []string `json:"out-of-step,omitempty"`
// a run's program's last line of standard output: raw when it is JSON, else a JSON string
Output any `json:"output,omitempty"`
// a run's program's first line of standard error, or why the step could not run it
Said string `json:"said,omitempty"`
Toolchain *ToolchainUsed `json:"toolchain,omitempty"`
// the compose-candidate verdict (the composer's own layout)
Verdict any `json:"verdict,omitempty"`
+139 -1
View File
@@ -174,6 +174,10 @@
"request"
]
},
"run": {
"$ref": "#/defs/RunJob",
"description": "a run: a program built from a change and run in the build seat's sandbox over the heads, its input asked of a verb of the asker's seat; the Go seat's check stream alone carries it, as a compose"
},
"needs": {
"type": "array",
"items": {
@@ -259,6 +263,129 @@
"built"
]
},
"RunJob": {
"type": "object",
"description": "a run ask's job: where its program is built, the heads it reads (each laid read-only at its repository's path), its input by reference, its arguments and what it is for",
"properties": {
"program": {
"$ref": "#/defs/RunProgram"
},
"heads": {
"type": "array",
"items": {
"$ref": "#/defs/RunHead"
},
"description": "the commits the program reads, a repository at most once"
},
"input": {
"$ref": "#/defs/RunInput"
},
"args": {
"type": "array",
"items": {
"type": "string"
},
"description": "the program's arguments, each a word or a flag"
},
"reader": {
"type": "string",
"description": "what the run is for, for a reader of the ask"
}
},
"required": [
"program",
"heads",
"input"
]
},
"RunProgram": {
"type": "object",
"description": "where a run's program is built: the repository and full commit fetched, the Go module's directory in it and the program's import path",
"properties": {
"repository": {
"type": "string"
},
"commit": {
"type": "string"
},
"dir": {
"type": "string"
},
"package": {
"type": "string"
}
},
"required": [
"repository",
"commit",
"dir",
"package"
]
},
"RunHead": {
"type": "object",
"description": "one commit a run's program reads",
"properties": {
"repository": {
"type": "string"
},
"commit": {
"type": "string"
}
},
"required": [
"repository",
"commit"
]
},
"RunInput": {
"type": "object",
"description": "a run's input by reference: the seat verb the asker serves it on (seat:<seat>.<verb>), the sha256 of its bytes and its size, at most 256 KiB",
"properties": {
"verb": {
"type": "string"
},
"digest": {
"type": "string",
"description": "64 lowercase hex digits"
},
"size": {
"type": "integer",
"description": "bytes"
}
},
"required": [
"verb",
"digest",
"size"
]
},
"RunAnswer": {
"type": "object",
"description": "what a run ask's step answers: whether this run built the program or took the one kept under its key, the key, the program's exit, the last line of its standard output and the first of its standard error",
"properties": {
"built": {
"type": "boolean"
},
"key": {
"type": "string"
},
"exit": {
"type": "integer"
},
"output": {
"description": "raw when it is JSON, else a JSON string"
},
"said": {
"type": "string"
}
},
"required": [
"built",
"key",
"exit"
]
},
"Step": {
"type": "object",
"properties": {
@@ -678,7 +805,7 @@
},
"StepResult": {
"type": "object",
"description": "what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the four",
"description": "what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a run's built, key, exit, output and said; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the five",
"properties": {
"artifacts": {
"type": "array",
@@ -736,6 +863,17 @@
"type": "string"
},
"description": "what the holder's node lacks of it"
},
"exit": {
"type": "integer",
"description": "a run's program's exit status"
},
"output": {
"description": "a run's program's last line of standard output: raw when it is JSON, else a JSON string"
},
"said": {
"type": "string",
"description": "a run's program's first line of standard error, or why the step could not run it"
}
}
},
@@ -9,6 +9,42 @@
"state": "running"
}
},
{
"name": "a pass judged by the checking program built at a mesh-delivery head",
"of": "state:verdicts/<group>.<heads>",
"given": {
"v": 1,
"group": "feat/registry",
"heads": "0123456789ab",
"state": "pass",
"levels": {
"unit": {
"run": 12,
"kept": 0
},
"integration": {
"run": 3,
"kept": 0
}
},
"judged-by": {
"program": {
"repository": "novox/mesh-delivery",
"commit": "0123456789abcdef0123456789abcdef01234567",
"dir": "modules/mesh-delivery-checker",
"package": "./cmd/mesh-checking-program"
},
"key": "program-0123456789abcdef",
"built": true,
"heads": [
{
"repository": "novox/mesh-delivery",
"commit": "0123456789abcdef0123456789abcdef01234567"
}
]
}
}
},
{
"name": "a kept pass",
"of": "state:kept/<level>.<digest>",
@@ -0,0 +1,17 @@
[
{
"name": "a checking program asks its input by its digest",
"of": "verb:input.input",
"given": {
"digest": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
},
{
"name": "the input answered as its exact bytes, base64",
"of": "verb:input.answer",
"given": {
"digest": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"input": "eyJ2IjoxfQ=="
}
}
]
@@ -140,6 +140,40 @@
"ended"
]
}
},
{
"name": "input",
"description": "A checking program's input the checker keeps, by the sha256 of its exact bytes: the facts of a check its verdict is asked of, or the heads its seat list is asked of, as a run ask names it (its input's verb and digest). Answers the digest and the bytes, base64; a digest it keeps no input of is an error. Asked by the build module that runs the program, as its manifest's invokes grants it. Read-only.",
"optional": true,
"input": {
"type": "object",
"properties": {
"digest": {
"type": "string",
"description": "the input's sha256, 64 lowercase hex digits, as the run ask names it"
}
},
"required": [
"digest"
]
},
"answer": {
"type": "object",
"properties": {
"digest": {
"type": "string",
"description": "the digest asked"
},
"input": {
"type": "string",
"description": "the input's exact bytes, base64, so no encoding on the way changes a byte the digest covers"
}
},
"required": [
"digest",
"input"
]
}
}
],
"description": "The merge check's tries: start one, read one, end one. The checker's own events stay under its own subjects (ADR 0620 §2).",
@@ -455,6 +489,65 @@
"to"
]
}
},
"judged-by": {
"type": "object",
"description": "the checking program that judged the check: where it was built, the key its build is kept under, whether this check's run built it, and the heads it read (ADR 0644, ADR 0656). Absent in a value written before it",
"properties": {
"program": {
"type": "object",
"properties": {
"repository": {
"type": "string"
},
"commit": {
"type": "string"
},
"dir": {
"type": "string"
},
"package": {
"type": "string"
}
},
"required": [
"repository",
"commit",
"dir",
"package"
]
},
"key": {
"type": "string",
"description": "program- and 16 hex digits"
},
"built": {
"type": "boolean"
},
"heads": {
"type": "array",
"items": {
"type": "object",
"properties": {
"repository": {
"type": "string"
},
"commit": {
"type": "string"
}
},
"required": [
"repository",
"commit"
]
}
}
},
"required": [
"program",
"key",
"heads"
]
}
},
"required": [
@@ -253,5 +253,64 @@
}
}
}
},
{
"name": "a run ask of the checking program over two heads",
"of": "accept:check",
"subject": "mesh.seat.node-build-go.accept.check",
"given": {
"v": 1,
"id": "r5e6",
"kind": "check",
"language": "go",
"asker": "mesh-delivery-checker",
"at": "2026-11-05T10:00:00Z",
"run": {
"program": {
"repository": "novox/mesh-delivery",
"commit": "0123456789abcdef0123456789abcdef01234567",
"dir": "modules/mesh-delivery-checker",
"package": "./cmd/mesh-checking-program"
},
"heads": [
{
"repository": "novox/mesh-delivery",
"commit": "0123456789abcdef0123456789abcdef01234567"
},
{
"repository": "novox/mesh-sdk",
"commit": "0123456789abcdef0123456789abcdef01234567"
}
],
"input": {
"verb": "seat:mesh-delivery-checker.input",
"digest": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"size": 7
},
"args": [
"-verdict"
],
"reader": "checking program of mesh-delivery head"
}
}
},
{
"name": "a finished run step whose program exited non-zero",
"of": "state:steps/<node>.<id>",
"given": {
"v": 1,
"id": "r5e6",
"tool": "check",
"node": "ace",
"state": "failed",
"started": "2026-11-05T10:00:00Z",
"ended": "2026-11-05T10:01:00Z",
"result": {
"built": true,
"key": "program-0123456789abcdef",
"exit": 2,
"said": "the facts name no head"
}
}
}
]
@@ -8,6 +8,7 @@ export const verbs = {
try: "try",
tryRead: "try-read",
tryEnd: "try-end",
input: "input",
} as const;
export const holderEvents = {
@@ -181,6 +182,20 @@ export interface TryEndAnswer {
"id": string;
}
/** is what input takes. */
export interface InputInput {
/** the input's sha256, 64 lowercase hex digits, as the run ask names it */
"digest": string;
}
/** is what input answers. */
export interface InputAnswer {
/** the digest asked */
"digest": string;
/** the input's exact bytes, base64, so no encoding on the way changes a byte the digest covers */
"input": string;
}
export interface VerdictHolderEventSeriesItem {
/** its artifact, or the package's ecosystem name as the module's packages name it */
"artifact": string;
@@ -247,6 +262,27 @@ export interface VerdictsByGroupHeadsValueFailuresItem {
"words"?: string;
}
export interface VerdictsByGroupHeadsValueJudgedByHeadsItem {
"commit": string;
"repository": string;
}
export interface VerdictsByGroupHeadsValueJudgedByProgram {
"commit": string;
"dir": string;
"package": string;
"repository": string;
}
/** the checking program that judged the check: where it was built, the key its build is kept under, whether this check's run built it, and the heads it read (ADR 0644, ADR 0656). Absent in a value written before it */
export interface VerdictsByGroupHeadsValueJudgedBy {
"built"?: boolean;
"heads": VerdictsByGroupHeadsValueJudgedByHeadsItem[];
/** program- and 16 hex digits */
"key": string;
"program": VerdictsByGroupHeadsValueJudgedByProgram;
}
export interface VerdictsByGroupHeadsValueLevelsValue {
"kept": number;
"run": number;
@@ -281,6 +317,8 @@ export interface VerdictsByGroupHeadsValue {
"group": string;
/** 12 hex digits */
"heads": string;
/** the checking program that judged the check: where it was built, the key its build is kept under, whether this check's run built it, and the heads it read (ADR 0644, ADR 0656). Absent in a value written before it */
"judged-by"?: VerdictsByGroupHeadsValueJudgedBy;
/** by level, unit or integration */
"levels"?: Record<string, VerdictsByGroupHeadsValueLevelsValue>;
"machines"?: string[];
@@ -129,6 +129,11 @@ export type PlacedBeside = buildStep.PlacedBeside;
export type Program = buildStep.Program;
export type ResumeAnswer = buildStep.ResumeAnswer;
export type ResumeInput = buildStep.ResumeInput;
export type RunAnswer = buildStep.RunAnswer;
export type RunHead = buildStep.RunHead;
export type RunInput = buildStep.RunInput;
export type RunJob = buildStep.RunJob;
export type RunProgram = buildStep.RunProgram;
export type Step = buildStep.Step;
export type StepAsk = buildStep.StepAsk;
export type StepAskBuild = buildStep.StepAskBuild;
@@ -197,6 +197,51 @@ export interface Program {
"path": string;
}
/** what a run ask's step answers: whether this run built the program or took the one kept under its key, the key, the program's exit, the last line of its standard output and the first of its standard error */
export interface RunAnswer {
"built": boolean;
"exit": number;
"key": string;
/** raw when it is JSON, else a JSON string */
"output"?: unknown;
"said"?: string;
}
/** one commit a run's program reads */
export interface RunHead {
"commit": string;
"repository": string;
}
/** a run's input by reference: the seat verb the asker serves it on (seat:<seat>.<verb>), the sha256 of its bytes and its size, at most 256 KiB */
export interface RunInput {
/** 64 lowercase hex digits */
"digest": string;
/** bytes */
"size": number;
"verb": string;
}
/** a run ask's job: where its program is built, the heads it reads (each laid read-only at its repository's path), its input by reference, its arguments and what it is for */
export interface RunJob {
/** the program's arguments, each a word or a flag */
"args"?: string[];
/** the commits the program reads, a repository at most once */
"heads": RunHead[];
"input": RunInput;
"program": RunProgram;
/** what the run is for, for a reader of the ask */
"reader"?: string;
}
/** where a run's program is built: the repository and full commit fetched, the Go module's directory in it and the program's import path */
export interface RunProgram {
"commit": string;
"dir": string;
"package": string;
"repository": string;
}
/** one step a build module runs on a node */
export interface Step {
/** when (RFC 3339 time) */
@@ -268,16 +313,20 @@ export interface StepAsk {
"needs"?: string[];
/** package to the tagged version a build pins */
"packages"?: Record<string, string>;
/** a run: a program built from a change and run in the build seat's sandbox over the heads, its input asked of a verb of the asker's seat; the Go seat's check stream alone carries it, as a compose */
"run"?: RunJob;
/** the layout version */
"v"?: number;
}
/** what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the four */
/** what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a run's built, key, exit, output and said; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the five */
export interface StepResult {
"artifacts"?: BuiltArtifact[];
"built"?: boolean;
/** the holder declined the ask: its node lacks what the ask needs */
"declined"?: boolean;
/** a run's program's exit status */
"exit"?: number;
"fetch"?: FetchAnswer;
"imports"?: string[];
"key"?: string;
@@ -287,6 +336,10 @@ export interface StepResult {
/** what the declined ask needs */
"needs"?: string[];
"out-of-step"?: string[];
/** a run's program's last line of standard output: raw when it is JSON, else a JSON string */
"output"?: unknown;
/** a run's program's first line of standard error, or why the step could not run it */
"said"?: string;
"toolchain"?: ToolchainUsed;
/** the compose-candidate verdict (the composer's own layout) */
"verdict"?: unknown;
@@ -129,6 +129,11 @@ export type PlacedBeside = buildStep.PlacedBeside;
export type Program = buildStep.Program;
export type ResumeAnswer = buildStep.ResumeAnswer;
export type ResumeInput = buildStep.ResumeInput;
export type RunAnswer = buildStep.RunAnswer;
export type RunHead = buildStep.RunHead;
export type RunInput = buildStep.RunInput;
export type RunJob = buildStep.RunJob;
export type RunProgram = buildStep.RunProgram;
export type Step = buildStep.Step;
export type StepAsk = buildStep.StepAsk;
export type StepAskBuild = buildStep.StepAskBuild;
@@ -197,6 +197,51 @@ export interface Program {
"path": string;
}
/** what a run ask's step answers: whether this run built the program or took the one kept under its key, the key, the program's exit, the last line of its standard output and the first of its standard error */
export interface RunAnswer {
"built": boolean;
"exit": number;
"key": string;
/** raw when it is JSON, else a JSON string */
"output"?: unknown;
"said"?: string;
}
/** one commit a run's program reads */
export interface RunHead {
"commit": string;
"repository": string;
}
/** a run's input by reference: the seat verb the asker serves it on (seat:<seat>.<verb>), the sha256 of its bytes and its size, at most 256 KiB */
export interface RunInput {
/** 64 lowercase hex digits */
"digest": string;
/** bytes */
"size": number;
"verb": string;
}
/** a run ask's job: where its program is built, the heads it reads (each laid read-only at its repository's path), its input by reference, its arguments and what it is for */
export interface RunJob {
/** the program's arguments, each a word or a flag */
"args"?: string[];
/** the commits the program reads, a repository at most once */
"heads": RunHead[];
"input": RunInput;
"program": RunProgram;
/** what the run is for, for a reader of the ask */
"reader"?: string;
}
/** where a run's program is built: the repository and full commit fetched, the Go module's directory in it and the program's import path */
export interface RunProgram {
"commit": string;
"dir": string;
"package": string;
"repository": string;
}
/** one step a build module runs on a node */
export interface Step {
/** when (RFC 3339 time) */
@@ -268,16 +313,20 @@ export interface StepAsk {
"needs"?: string[];
/** package to the tagged version a build pins */
"packages"?: Record<string, string>;
/** a run: a program built from a change and run in the build seat's sandbox over the heads, its input asked of a verb of the asker's seat; the Go seat's check stream alone carries it, as a compose */
"run"?: RunJob;
/** the layout version */
"v"?: number;
}
/** what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the four */
/** what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a run's built, key, exit, output and said; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the five */
export interface StepResult {
"artifacts"?: BuiltArtifact[];
"built"?: boolean;
/** the holder declined the ask: its node lacks what the ask needs */
"declined"?: boolean;
/** a run's program's exit status */
"exit"?: number;
"fetch"?: FetchAnswer;
"imports"?: string[];
"key"?: string;
@@ -287,6 +336,10 @@ export interface StepResult {
/** what the declined ask needs */
"needs"?: string[];
"out-of-step"?: string[];
/** a run's program's last line of standard output: raw when it is JSON, else a JSON string */
"output"?: unknown;
/** a run's program's first line of standard error, or why the step could not run it */
"said"?: string;
"toolchain"?: ToolchainUsed;
/** the compose-candidate verdict (the composer's own layout) */
"verdict"?: unknown;
@@ -129,6 +129,11 @@ export type PlacedBeside = buildStep.PlacedBeside;
export type Program = buildStep.Program;
export type ResumeAnswer = buildStep.ResumeAnswer;
export type ResumeInput = buildStep.ResumeInput;
export type RunAnswer = buildStep.RunAnswer;
export type RunHead = buildStep.RunHead;
export type RunInput = buildStep.RunInput;
export type RunJob = buildStep.RunJob;
export type RunProgram = buildStep.RunProgram;
export type Step = buildStep.Step;
export type StepAsk = buildStep.StepAsk;
export type StepAskBuild = buildStep.StepAskBuild;
@@ -197,6 +197,51 @@ export interface Program {
"path": string;
}
/** what a run ask's step answers: whether this run built the program or took the one kept under its key, the key, the program's exit, the last line of its standard output and the first of its standard error */
export interface RunAnswer {
"built": boolean;
"exit": number;
"key": string;
/** raw when it is JSON, else a JSON string */
"output"?: unknown;
"said"?: string;
}
/** one commit a run's program reads */
export interface RunHead {
"commit": string;
"repository": string;
}
/** a run's input by reference: the seat verb the asker serves it on (seat:<seat>.<verb>), the sha256 of its bytes and its size, at most 256 KiB */
export interface RunInput {
/** 64 lowercase hex digits */
"digest": string;
/** bytes */
"size": number;
"verb": string;
}
/** a run ask's job: where its program is built, the heads it reads (each laid read-only at its repository's path), its input by reference, its arguments and what it is for */
export interface RunJob {
/** the program's arguments, each a word or a flag */
"args"?: string[];
/** the commits the program reads, a repository at most once */
"heads": RunHead[];
"input": RunInput;
"program": RunProgram;
/** what the run is for, for a reader of the ask */
"reader"?: string;
}
/** where a run's program is built: the repository and full commit fetched, the Go module's directory in it and the program's import path */
export interface RunProgram {
"commit": string;
"dir": string;
"package": string;
"repository": string;
}
/** one step a build module runs on a node */
export interface Step {
/** when (RFC 3339 time) */
@@ -268,16 +313,20 @@ export interface StepAsk {
"needs"?: string[];
/** package to the tagged version a build pins */
"packages"?: Record<string, string>;
/** a run: a program built from a change and run in the build seat's sandbox over the heads, its input asked of a verb of the asker's seat; the Go seat's check stream alone carries it, as a compose */
"run"?: RunJob;
/** the layout version */
"v"?: number;
}
/** what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the four */
/** what a step answered, by the kind of ask: a build's artifacts, toolchain, imports and out-of-step modules; a check's fetch and levels; a compose's built, key and verdict; a run's built, key, exit, output and said; a declined ask's declined, needs and lacks. The fields of the kinds do not meet, so one layout holds the five */
export interface StepResult {
"artifacts"?: BuiltArtifact[];
"built"?: boolean;
/** the holder declined the ask: its node lacks what the ask needs */
"declined"?: boolean;
/** a run's program's exit status */
"exit"?: number;
"fetch"?: FetchAnswer;
"imports"?: string[];
"key"?: string;
@@ -287,6 +336,10 @@ export interface StepResult {
/** what the declined ask needs */
"needs"?: string[];
"out-of-step"?: string[];
/** a run's program's last line of standard output: raw when it is JSON, else a JSON string */
"output"?: unknown;
/** a run's program's first line of standard error, or why the step could not run it */
"said"?: string;
"toolchain"?: ToolchainUsed;
/** the compose-candidate verdict (the composer's own layout) */
"verdict"?: unknown;