Write the facts snapshot in format 2, with each machine's grants and credential bindings (design 47 R4c-2, issue 1394)

Every reader takes format 2 since R4b (ADR 0456 clause 1), and the assigner's composition check reads the grants and bindings (ADR 0456 clause 2): the writer moves now, names only, never a sealed value.
This commit is contained in:
2026-10-20 18:26:07 +00:00
parent f2d7bc9480
commit b75fb7899e
3 changed files with 69 additions and 22 deletions
+21 -4
View File
@@ -169,10 +169,10 @@ func factsStore(ctx context.Context, open *stores) (string, error) {
return address, nil
}
// writtenFormat is the format of the snapshot this controller writes: 1, the format its own reader knew before mesh-sdk's
// go/facts took the type over (issue 1390, novox/hq ADR 0456). The readers (the merge gate, the check) read formats 1 and
// 2; the writer moves to 2, which also carries each machine's grants and bindings, in a later release of its own.
const writtenFormat = 1
// writtenFormat is the format of the snapshot this controller writes: mesh-sdk's go/facts current format, 2, which carries
// each machine's grants and credential bindings besides everything format 1 held (issue 1394, novox/hq ADR 0456 clause 2).
// Every reader (the merge gate, the build seat's check) reads formats 1 and 2.
const writtenFormat = snapshot.Format
// gatherFacts composes one snapshot from the store: read only, nothing made, nothing sent.
func gatherFacts(ctx context.Context, open *stores, busVersion string) (snapshot.Facts, error) {
@@ -367,6 +367,23 @@ func gatherFacts(ctx context.Context, open *stores, busVersion string) (snapshot
m.Settings = append(m.Settings, snapshot.Settings{Module: module, Values: scrub.Values(layer.Whole())})
}
}
// Who was issued a credential by this machine, by name only: never what the credential is, sealed or not.
issued, err := inv.SecretsFrom(ctx, n.Name)
if err != nil {
return snapshot.Facts{}, err
}
for _, g := range issued {
m.Grants = append(m.Grants, scrub.Grant(g.Name, g.Consumer, g.ConsumerModule, g.Local))
}
bound, err := inv.BindingsFor(ctx, n.Name)
if err != nil {
return snapshot.Facts{}, err
}
for consumer, byProvision := range bound {
for provision, c := range byProvision {
m.Bindings = append(m.Bindings, scrub.Binding(consumer, provision, c.Node, c.Module))
}
}
m.Declaration = declarationFacts(ctx, open, n.Name, gensErr, scrub)
if ctx.Err() != nil {
return snapshot.Facts{}, ctx.Err()