Carry each contribution, composed, and the consumer's address in its plan entry, and let a process read another module's state, so route-proxy serves routes from the seat's plans alone (issue 774, research 072 row 34)

This commit is contained in:
2026-10-31 09:27:26 +01:00
parent a320f8e2cd
commit a4e7629742
6 changed files with 121 additions and 5 deletions
+22 -3
View File
@@ -43,9 +43,28 @@ func (s State) bucket() string { return s.Module + "_" + s.Name }
// (js.KeyValue) is what asks $JS.API.STREAM.INFO.KV_<bucket>, so it is what withRefusal watches: a bucket
// not granted is refused there, promptly, as nats.ErrPermissionViolation.
func (c *Conn) State(name string) State {
bucket := c.account.Module + "_" + name
return State{Module: c.account.Module, Name: name, closed: func() bool { return c.nc.IsClosed() }, kv: func(ctx context.Context) (jetstream.KeyValue, error) {
if err := c.refusedUnannounced(name); err != nil {
return c.bound(c.account.Module, name, func() error { return c.refusedUnannounced(name) })
}
// Read is another module's state this connection's module reads, named as its manifest's `reads` names it
// (`<module>.<state>`, novox/hq ADR 0495): bound like State to the bucket <module>_<state>, so Get, Keys and Watch
// work as far as the account's read grant goes, and a write is refused by the bus (issue 774: route-proxy follows
// the seat mesh-provisioner's plans). A name that is not `<module>.<state>` fails at the call that needed it.
func (c *Conn) Read(read string) State {
module, name, ok := strings.Cut(read, ".")
return c.bound(module, name, func() error {
if !ok || module == "" || name == "" || strings.Contains(name, ".") {
return fmt.Errorf("%q is not a state another module keeps, <module>.<state>", read)
}
return nil
})
}
// bound is module's state name on this connection, checked by refused before every bind.
func (c *Conn) bound(module, name string, refused func() error) State {
bucket := module + "_" + name
return State{Module: module, Name: name, closed: func() bool { return c.nc.IsClosed() }, kv: func(ctx context.Context) (jetstream.KeyValue, error) {
if err := refused(); err != nil {
return nil, err
}
js, err := jetstream.New(c.nc)