K25 (D-33): the node-engine's first-views answers entries and wants, and the seat gains entry-again
Builds: design 47 G §698 (§683, §422) Claude-Session: https://claude.ai/code/session_01JG73KEq4zoDfM9WtYpcQgZ
This commit is contained in:
@@ -30,6 +30,7 @@ const (
|
||||
VerbSeatListAgain = "seat-list-again"
|
||||
VerbFirstViews = "first-views"
|
||||
VerbFirstViewAgain = "first-view-again"
|
||||
VerbEntryAgain = "entry-again"
|
||||
VerbProcessBuilds = "process-builds"
|
||||
)
|
||||
|
||||
@@ -46,7 +47,7 @@ const (
|
||||
|
||||
// Verbs is every verb the seat serves, in its definition's order: a new copy each call.
|
||||
func Verbs() []string {
|
||||
return []string{VerbHandOver, VerbAccessAct, VerbJudgeDirectories, VerbSetuidSearch, VerbRootFree, VerbActs, VerbPackages, VerbComposition, VerbCompose, VerbComposeCandidate, VerbManifestReads, VerbSeatList, VerbSeatListAgain, VerbFirstViews, VerbFirstViewAgain, VerbProcessBuilds}
|
||||
return []string{VerbHandOver, VerbAccessAct, VerbJudgeDirectories, VerbSetuidSearch, VerbRootFree, VerbActs, VerbPackages, VerbComposition, VerbCompose, VerbComposeCandidate, VerbManifestReads, VerbSeatList, VerbSeatListAgain, VerbFirstViews, VerbFirstViewAgain, VerbEntryAgain, VerbProcessBuilds}
|
||||
}
|
||||
|
||||
// Events is every event published on the seat's subject: a new copy each call.
|
||||
@@ -1366,10 +1367,41 @@ type SeatListAgainAnswer = SeatList
|
||||
type FirstViewsInput struct {
|
||||
}
|
||||
|
||||
// FirstViewsAnswerEntriesItem is a type of the contract.
|
||||
type FirstViewsAnswerEntriesItem struct {
|
||||
// the build's fingerprint
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
// since when it stands in that state, RFC 3339
|
||||
Since time.Time `json:"since"`
|
||||
// asked of the indexer, answered, or not found by it
|
||||
State string `json:"state"`
|
||||
}
|
||||
|
||||
// The values of FirstViewsAnswerEntriesItem's state.
|
||||
const (
|
||||
FirstViewsAnswerEntriesItemStateAsked = "asked"
|
||||
FirstViewsAnswerEntriesItemStateAnswered = "answered"
|
||||
FirstViewsAnswerEntriesItemStateNotFound = "not-found"
|
||||
)
|
||||
|
||||
// FirstViewsAnswerWantsItem is a type of the contract.
|
||||
type FirstViewsAnswerWantsItem struct {
|
||||
// the fingerprint wanted
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
// since when the want is kept, RFC 3339
|
||||
KeptSince time.Time `json:"kept-since"`
|
||||
// the module the want is of
|
||||
Module string `json:"module"`
|
||||
}
|
||||
|
||||
// FirstViewsAnswer is what first-views answers.
|
||||
type FirstViewsAnswer struct {
|
||||
// one row per entry the node-engine keeps of a module's build by its fingerprint: when it asked the indexer's entry and where that stands (design 47 G 698)
|
||||
Entries []FirstViewsAnswerEntriesItem `json:"entries"`
|
||||
// one status per owner and state followed, as mesh-sdk's views runtime keeps it
|
||||
FirstViews []map[string]any `json:"first-views"`
|
||||
// the wants the node-engine keeps (design 47 G 683, 698)
|
||||
Wants []FirstViewsAnswerWantsItem `json:"wants"`
|
||||
}
|
||||
|
||||
// FirstViewAgainInput is what first-view-again takes.
|
||||
@@ -1406,6 +1438,36 @@ type FirstViewAgainAnswer struct {
|
||||
Read string `json:"read"`
|
||||
}
|
||||
|
||||
// EntryAgainInput is what entry-again takes.
|
||||
type EntryAgainInput struct {
|
||||
// the build's fingerprint, as first-views' entries name it
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
// why it is asked again, in plain words
|
||||
Why string `json:"why"`
|
||||
}
|
||||
|
||||
// EntryAgainAnswerAsked is the hand ask written.
|
||||
type EntryAgainAnswerAsked struct {
|
||||
// when it was asked, RFC 3339
|
||||
At time.Time `json:"at"`
|
||||
// the caller the runtime proved
|
||||
By string `json:"by"`
|
||||
// the build's fingerprint
|
||||
Fingerprint string `json:"fingerprint"`
|
||||
// the layout's version
|
||||
V int64 `json:"v"`
|
||||
// why it was asked again
|
||||
Why string `json:"why"`
|
||||
}
|
||||
|
||||
// EntryAgainAnswer is what entry-again answers.
|
||||
type EntryAgainAnswer struct {
|
||||
// the hand ask written
|
||||
Asked EntryAgainAnswerAsked `json:"asked"`
|
||||
// the verb that reads the status, first-views
|
||||
Read string `json:"read"`
|
||||
}
|
||||
|
||||
// ProcessBuildsInput is what process-builds takes.
|
||||
type ProcessBuildsInput struct {
|
||||
// only this module's processes
|
||||
|
||||
@@ -115,6 +115,12 @@ func TestFixtures(t *testing.T) {
|
||||
decode: func(b []byte) (any, error) { var v ProcessBuildsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "first-view-again names the owner, its state and why", subject: "", given: "{\"owner\":\"mesh-delivery-indexer\",\"state\":\"manifests\",\"why\":\"the picture lags the indexer by hand\"}", wire: "{\"owner\":\"mesh-delivery-indexer\",\"state\":\"manifests\",\"why\":\"the picture lags the indexer by hand\"}",
|
||||
decode: func(b []byte) (any, error) { var v FirstViewAgainInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "first-views answers its entries and its kept wants", subject: "", given: "{\"entries\":[{\"fingerprint\":\"b3f1c9\",\"since\":\"2026-11-11T08:00:00Z\",\"state\":\"asked\"},{\"fingerprint\":\"a77d02\",\"since\":\"2026-11-11T08:01:00Z\",\"state\":\"answered\"},{\"fingerprint\":\"0c1e55\",\"since\":\"2026-11-11T08:02:00Z\",\"state\":\"not-found\"}],\"first-views\":[],\"wants\":[{\"fingerprint\":\"b3f1c9\",\"kept-since\":\"2026-11-11T07:00:00Z\",\"module\":\"mesh-delivery-indexer\"}]}", wire: "{\"entries\":[{\"fingerprint\":\"b3f1c9\",\"since\":\"2026-11-11T08:00:00Z\",\"state\":\"asked\"},{\"fingerprint\":\"a77d02\",\"since\":\"2026-11-11T08:01:00Z\",\"state\":\"answered\"},{\"fingerprint\":\"0c1e55\",\"since\":\"2026-11-11T08:02:00Z\",\"state\":\"not-found\"}],\"first-views\":[],\"wants\":[{\"fingerprint\":\"b3f1c9\",\"kept-since\":\"2026-11-11T07:00:00Z\",\"module\":\"mesh-delivery-indexer\"}]}",
|
||||
decode: func(b []byte) (any, error) { var v FirstViewsAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "entry-again names the fingerprint and why", subject: "", given: "{\"fingerprint\":\"b3f1c9\",\"why\":\"the entry could not be read\"}", wire: "{\"fingerprint\":\"b3f1c9\",\"why\":\"the entry could not be read\"}",
|
||||
decode: func(b []byte) (any, error) { var v EntryAgainInput; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
{name: "entry-again answers what was asked and where it is read", subject: "", given: "{\"asked\":{\"at\":\"2026-11-11T08:00:00Z\",\"by\":\"operator@shanks\",\"fingerprint\":\"b3f1c9\",\"v\":1,\"why\":\"the entry could not be read\"},\"read\":\"first-views\"}", wire: "{\"asked\":{\"at\":\"2026-11-11T08:00:00Z\",\"by\":\"operator@shanks\",\"fingerprint\":\"b3f1c9\",\"v\":1,\"why\":\"the entry could not be read\"},\"read\":\"first-views\"}",
|
||||
decode: func(b []byte) (any, error) { var v EntryAgainAnswer; err := json.Unmarshal(b, &v); return v, err }, subjectIs: nil},
|
||||
}
|
||||
for _, c := range cases {
|
||||
v, err := c.decode([]byte(c.given))
|
||||
|
||||
Reference in New Issue
Block a user