package delivery import ( "encoding/json" "fmt" ) // The holder's question before it stores a publish (novox/hq ADR 0605 §4, design 51 *Publishing*): did the builder // number this version with this digest? Every registry seat's holder asks it the same way, so the asking lives here // once (ADR 0627 §2), beside the builder's layouts; no holder writes it again. // // The builder answers it today only as its module's tool builder_versions: no seat in the seat set names the builder's // role yet. Once one does, BuilderVersionsAddress becomes that seat's verb and nothing else changes for a holder. const BuilderVersionsAddress = BuilderModule + ".builder_versions" // AskFunc is the runtime's request and reply over the bus (mesh-sdk stdio.Ask), given by the holder so this package does // not depend on the runtime. type AskFunc func(address string, body any) (json.RawMessage, error) // BuilderVersions asks the builder whether it numbered a version with a digest. It answers the holder's Check: // recorded, and why not when it is not. type BuilderVersions struct{ Ask AskFunc } // Recorded asks the builder about name@version with digest. An answer without `recorded` is an error, never a yes. func (b BuilderVersions) Recorded(name, version, digest string) (bool, string, error) { raw, err := b.Ask(BuilderVersionsAddress, map[string]any{"name": name, "version": version, "digest": digest}) if err != nil { return false, "", err } var a struct { Recorded *bool `json:"recorded"` Why string `json:"why"` } if err := json.Unmarshal(raw, &a); err != nil || a.Recorded == nil { return false, "", fmt.Errorf("builder_versions answered no recorded: %s", raw) } return *a.Recorded, a.Why, nil }