The tool runner reads its membership from the grants part's state alone: no stream read, no subject heard (ADR 0571 §10)
Follow no longer asks the ASSIGNMENTS stream for a copy nor subscribes mesh.assignment; a module with no membership key is said so and served in its derived shape. The test mesh issues memberships where the grants part keeps them. Tests: none added; the stream-fallback assertions of two existing tests are replaced by their state-only counterparts, and the test mesh no longer makes the stream. The two integration tests of the bus were run locally against the embedded bus. (issue 774, 774/S32) Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
@@ -119,25 +119,24 @@ func TestAWatchIsRefusedWhenNoCurrentValueIsTakenWithinTheBound(t *testing.T) {
|
||||
|
||||
// **A membership the grants part wrote in its old wrapper is served whole** (issue 774). Until 2026-10-30 the part wrote
|
||||
// its pass record, the membership inside, into its state memberships; the tool runner read the value as a bare
|
||||
// membership, took it over the assignments stream's copy, and served no tool and no state. This is what the live mesh
|
||||
// held: read through mesh-sdk's codec, its tools are answered where the membership says and its state is reached.
|
||||
// membership, and served no tool and no state. This is what the live mesh held: read through mesh-sdk's codec, its tools
|
||||
// are answered where the membership says and its state is reached. A held-back one's wrapper is refused, and the module has
|
||||
// no membership then (774/S32/AC2: no stream is read in its place).
|
||||
func TestAMembershipTheGrantsPartWroteWrappedIsServed(t *testing.T) {
|
||||
mesh := mt.New(t)
|
||||
mesh.Bucket(t, "gitea_repos")
|
||||
gitea := mt.MembershipOf("gitea", "anchor", false, nil)
|
||||
gitea.State = []bus.StateIssued{{Name: "repos", Bucket: "gitea_repos", Writes: true}}
|
||||
mesh.IssueInGrantsWrapped(t, gitea, "published")
|
||||
// The old wrapper of a membership the part held back carries its unpublished composition: refused, so the
|
||||
// assignments stream's copy is served, never what the hold kept back.
|
||||
pages := mt.MembershipOf("pages", "anchor", false, nil)
|
||||
mesh.Issue(t, pages)
|
||||
// The old wrapper of a membership the part held back carries its unpublished composition: refused, never served.
|
||||
heldBack := mt.MembershipOf("pages", "anchor", true, nil)
|
||||
mesh.IssueInGrantsWrapped(t, heldBack, "not published, a shadow difference: publishing would lose the last holder of x")
|
||||
conn, err := bus.Connect(bus.Credential{URL: mt.URL(t), Module: "node-tools", Node: "anchor"})
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
conn.Logf = func(string, ...any) {}
|
||||
var logged []string
|
||||
conn.Logf = func(f string, a ...any) { logged = append(logged, fmt.Sprintf(f, a...)) }
|
||||
t.Cleanup(conn.Close)
|
||||
conn.Follow("gitea")
|
||||
mt.Until(t, func() error {
|
||||
@@ -156,14 +155,9 @@ func TestAMembershipTheGrantsPartWroteWrappedIsServed(t *testing.T) {
|
||||
t.Errorf("the state reads back %+v, %v", e, err)
|
||||
}
|
||||
conn.Follow("pages")
|
||||
mt.Until(t, func() error {
|
||||
if m := conn.Membership("pages"); m == nil || len(m.Serves) == 0 {
|
||||
return fmt.Errorf("pages' membership is %+v, want the assignments stream's", m)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if got, want := fmt.Sprint(conn.ServedOn("pages", "pages_list")), "[{mesh.mod.pages.tool.pages_list.anchor }]"; got != want {
|
||||
t.Errorf("a held-back membership's wrapper is served: pages_list on %s, want the stream's %s", got, want)
|
||||
time.Sleep(300 * time.Millisecond)
|
||||
if m := conn.Membership("pages"); m != nil || !strings.Contains(strings.Join(logged, "\n"), "no membership issued for pages") {
|
||||
t.Errorf("a held-back membership's wrapper was served or not said: %+v, %q", m, logged)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user