Bootstrap the seat mesh-delivery so a runner admits its source before the seat list is read (A-362)

The catalog half is read through mesh-delivery's source as well as mesh-catalog's verbs, and a runner with an unread
seat list admitted only the latter. The bootstrapped copy is mesh-delivery main 21eaa55b's contract file, byte for
byte; the tests' seat list and the captured beside copy take the same file.

Builds: design 47 G lead answers A-362, A-353

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-13 17:45:44 +01:00
parent affde04396
commit ab355879f0
5 changed files with 2499 additions and 8 deletions
File diff suppressed because it is too large Load Diff
+1
View File
@@ -26,6 +26,7 @@ func TestEveryBootstrappedDefinitionEqualsItsContractsFile(t *testing.T) {
{"operator-channel", "mesh-contracts", "operator-and-conversation/seats/operator-channel/seat.json"},
{"mesh-catalog", "mesh-delivery", "modules/mesh-delivery-contracts/seats/mesh-catalog/seat.json"},
{"mesh-delivery-checker", "mesh-delivery", "modules/mesh-delivery-contracts/seats/mesh-delivery-checker/seat.json"},
{"mesh-delivery", "mesh-delivery", "modules/mesh-delivery-contracts/seats/mesh-delivery/seat.json"},
}
var have []string
for _, d := range Bootstrapped() {
+8
View File
@@ -6,6 +6,7 @@ import (
"errors"
"fmt"
"reflect"
"slices"
"strings"
"testing"
"time"
@@ -182,6 +183,13 @@ func TestTheBootstrapIsHeldAndNothingNewIsActedOnUntilTheSeatAnswers(t *testing.
if got := len(r.Definitions()); got != len(boot) {
t.Fatalf("the reader holds %d definitions, the bootstrap has %d", got, len(boot))
}
// Design 47 G lead answers A-353, A-362: before the list is read the runner admits the seat verbs its catalog half is
// read by, mesh-delivery's source beside mesh-catalog's registrations, revision and entry.
for _, sv := range [][2]string{{"mesh-catalog", "registrations"}, {"mesh-catalog", "revision"}, {"mesh-catalog", "entry"}, {"mesh-delivery", "source"}} {
if !slices.ContainsFunc(r.Definitions()[sv[0]].Verbs, func(v seatdef.Verb) bool { return v.Name == sv[1] }) {
t.Errorf("with the seat list unread the reader holds no %s.%s", sv[0], sv[1])
}
}
st := r.Status()
if st.Heard || len(st.Waiting) != len(boot) || st.LastError == "" || st.Health() == "" {
t.Fatalf("status %+v: want the seat not heard, every bootstrapped seat waiting, the error and the health said", st)
@@ -101,18 +101,15 @@
},
{
"name": "source",
"description": "One watched branch's source revision (design 47 *Watched branches and the catalog graph per branch*: source.<branch> in place of source.main): The source revision the gate holds: every repository it names, its trunk branch and that trunk's head as the gate merged or seeded it, and the group that moved it last. Read, never written: the node-engines read it to call a reverted build's catch-up tool once per repository, never the gate's state (design 47).",
"description": "One watched branch's source revision (design 47 *Watched branches and the catalog graph per branch*: source.<branch> in place of source.main): The source revision the gate holds: every repository it names, its trunk branch and that trunk's head as the gate merged or seeded it, and the group that moved it last. Read, never written: the node-engines read it to call a reverted build's catch-up tool once per repository, never the gate's state (design 47). Given no branch it answers branches alone, the branch of each source key the gate keeps; given a branch, that branch's source revision (design 47 G section 690).",
"input": {
"type": "object",
"properties": {
"branch": {
"type": "string",
"description": "the watched branch, escaped as a key name is"
"description": "the watched branch, escaped as a key name is; absent: the answer is the list of the branches the gate keeps a source revision of (design 47 G section 690)"
}
},
"required": [
"branch"
]
}
},
"answer": {
"type": "object",
@@ -139,6 +136,13 @@
"branch": {
"type": "string",
"description": "the watched branch the source revision is of"
},
"branches": {
"type": "array",
"items": {
"type": "string"
},
"description": "given no branch: the branch name of each source.<branch> key the gate keeps, which every reader of the catalog half follows before the first registrations (design 47 G section 614, section 690)"
}
}
},
@@ -304,6 +308,22 @@
"type": "boolean",
"description": "a merge made at the forge, with no Approve"
},
"repository": {
"type": "string",
"description": "for a forge-made record, the repository, <owner>/<name>"
},
"pull": {
"type": "integer",
"description": "for a forge-made record, the pull request's number"
},
"commit": {
"type": "string",
"description": "for a forge-made record, the merge commit"
},
"branch": {
"type": "string",
"description": "for a forge-made record, the branch the merge moved"
},
"at": {
"type": "string",
"format": "date-time",
@@ -429,6 +449,14 @@
"type": "string",
"description": "the repository"
},
"module": {
"type": "string",
"description": "the module the merge changed, from the delivery record"
},
"branch": {
"type": "string",
"description": "the watched branch the merge moved"
},
"commit": {
"type": "string",
"description": "the merge commit"
@@ -453,6 +481,65 @@
"why"
]
}
},
{
"name": "approval-carried",
"subject": "approval-carried.<repository>.<pull>",
"keep": {
"max-age-days": 90
},
"body": {
"type": "object",
"description": "an Approve given before G, carried as that pull request's approval step: said at G's switch for each merges key the old bridge had not performed (design 47 G 542)",
"properties": {
"repository": {
"type": "string",
"description": "the repository"
},
"pull": {
"type": "integer",
"description": "the pull request's number",
"minimum": 1
},
"commit": {
"type": "string",
"description": "the head the Approve named"
},
"approver": {
"type": "string",
"description": "who approved: the operator"
},
"at": {
"type": "string",
"description": "when it was said, RFC 3339",
"format": "date-time"
}
},
"required": [
"repository",
"pull",
"commit",
"approver",
"at"
]
}
},
{
"name": "pins-stated",
"body": {
"type": "object",
"description": "the gate states every pin it holds once its pinned events are said, so an indexer whose state pins was made later hears them all; kept as pinned is, on the seat's family (design 47 G 579, 652)",
"properties": {
"at": {
"type": "string",
"description": "when it was said, RFC 3339",
"format": "date-time"
}
},
"required": [
"at"
]
}
}
],
"states": [
@@ -992,9 +1079,24 @@
"catalog": {
"type": "array",
"items": {
"type": "integer"
"type": "object",
"description": "one catalog graph revision, named by its watched branch and its number on the seat mesh-catalog (revisions are numbered per branch)",
"properties": {
"branch": {
"type": "string",
"description": "the watched branch the revision belongs to"
},
"revision": {
"type": "integer",
"description": "its number on that branch"
}
},
"required": [
"branch",
"revision"
]
},
"description": "catalog graph revisions, by their number on the seat mesh-catalog"
"description": "catalog graph revisions, by watched branch and number on the seat mesh-catalog"
},
"assignment": {
"type": "array",