TLS-5 grants: the tool runner's consumes of the owners' views get their durable consumers and its findings state its grant, as any manifest's (A7's request; ADR 0615 §5)

Nothing in the composition changes for it: the consumers on module streams are made since
DLV-G1. The row proves it on the tool runner's own manifest.

Claude-Session: https://claude.ai/code/session_01JG73KJNrH5EgFXMKKYSrig
This commit is contained in:
2026-11-04 12:34:50 +01:00
parent 5b68106662
commit 56891abe20
+31
View File
@@ -2271,6 +2271,37 @@ func TestGrants(t *testing.T) {
}
})
// TLS-5 (A7's request; ADR 0615 §5): the tool runner, which consumes the owners' views events and keeps a findings state,
// gets its durable consumer on each views stream, made by the part, and its own findings bucket, as any manifest's.
t.Run("the tool runner's consumes of the owners' views get their consumers, and its findings state its grant", func(t *testing.T) {
b := fixture()
b.manifestOf("mesh-delivery-indexer", `{"module":"mesh-delivery-indexer","version":"1","own-secrets":{"broker":"/var/lib/i/broker"},`+
`"emits":["views.manifests","views.modules"],"streams":[{"name":"indexer-views","events":["views.*"],"max-age-days":7,"max-mib":256}]}`)
b.manifestOf("mesh-delivery-assigner", `{"module":"mesh-delivery-assigner","version":"1","own-secrets":{"broker":"/var/lib/as/broker"},`+
`"emits":["views.placement","views.seat-holders"],"streams":[{"name":"assigner-views","events":["views.*"],"max-age-days":7,"max-mib":256}]}`)
b.manifestOf("node-tools", `{"module":"node-tools","version":"1","tool-runner":true,"own-secrets":{"broker":"/var/lib/nt/broker"},`+
`"consumes":["mesh-delivery-assigner.views.placement","mesh-delivery-assigner.views.seat-holders","mesh-delivery-indexer.views.manifests",`+
`"mesh-delivery-indexer.views.modules"],"state":[{"name":"findings","history":5}]}`)
for _, m := range []string{"mesh-delivery-indexer", "mesh-delivery-assigner", "node-tools"} {
b.assign("a", m)
}
p := partOn(b)
p.Consumers = b
p.Compose()
for _, c := range []string{"INDEXER_VIEWS.a_node-tools", "ASSIGNER_VIEWS.a_node-tools"} {
if !slices.Contains(b.consumerCreates, c) {
t.Errorf("the tool runner's consumer %s was not made: %v", c, b.consumerCreates)
}
}
users := shadowOf(t, b)
runner := users[slices.IndexFunc(users, func(u grants.User) bool { return u.User == "a.node-tools" })]
for _, s := range []string{"$JS.API.CONSUMER.MSG.NEXT.INDEXER_VIEWS.a_node-tools", "$KV.node-tools_findings.>"} {
if !slices.ContainsFunc(runner.Publish, func(g string) bool { return buscompose.SubjectsOverlap(g, s) }) {
t.Errorf("the tool runner may not publish %s: %v", s, runner.Publish)
}
}
})
// 774/AC4 (novox/hq ADR 0561 §2): every account the vault mints that the records compose is written to the state
// accounts once, with the bus's address and a module's claims, read by the vault alone; a key is deleted when placement
// no longer names its user, and never in a pass whose reads failed.