D1 (assigner): the states the views family says are named when it starts, not when the package loads

viewedStates read the module before the start had said it, so every name began with an underscore at run time; it is a function now.

Builds: design 47 G A-296, §428

Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
2026-11-12 22:51:06 +01:00
parent de24c7f07c
commit bc8d3e1499
3 changed files with 16 additions and 14 deletions
@@ -1640,7 +1640,7 @@ func TestAProposalIsAnsweredApprovedAndWritten(t *testing.T) {
// the bucket does, and checks that no views event landed where a waiter on the assigner's put waits.
func (b *bed) viewsHold(t *testing.T, state, key string) {
t.Helper()
kv, marks := b.buckets[viewedStates[state]], b.buckets[marksBucket()]
kv, marks := b.buckets[viewedStates()[state]], b.buckets[marksBucket()]
src := func(kv jetstream.KeyValue) views.Source { return bedSource{b.ctx, kv} }
st, err := b.js.Stream(b.ctx, "EVENTS")
if err != nil {
@@ -1829,7 +1829,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][]
if name == views.MarksState {
return bedSource{b.ctx, b.buckets[marksBucket()]}
}
return bedSource{b.ctx, b.buckets[viewedStates[name]]}
return bedSource{b.ctx, b.buckets[viewedStates()[name]]}
}
// The runtime: one bundle on a pair of pipes, a call on mesh.mod.<module>.call.<tool>.<caller token> handed to it with
// the caller in _meta, its answer replied as the tool runner replies ({result, error, node}).
@@ -1906,7 +1906,7 @@ func firstViewsBeforeAnyNewFormState(t *testing.T, b *bed, granted map[string][]
case slices.Contains(allowed, user) && err != nil:
t.Errorf("%s's first view of %s before any new-form state: %v", user, tool, err)
case slices.Contains(allowed, user):
keys, _ := b.buckets[viewedStates[tool]].Keys(b.ctx)
keys, _ := b.buckets[viewedStates()[tool]].Keys(b.ctx)
if a.Owner != assignment.Module() || a.State != tool || len(a.Values) != len(keys) {
t.Errorf("%s's first view of %s = %+v, the state holds %v", user, tool, a, keys)
}
@@ -279,7 +279,7 @@ func run(ctx context.Context, getenv func(string) string, logOut io.Writer) erro
}
// Each change of the states its readers read is said on its views family (ADR 0615 §5, ADR 0619 §2); a watch of it
// that ends stops the program, as a watch of what a pass reads does.
viewErrs := make(chan error, len(viewedStates))
viewErrs := make(chan error, len(viewedStates()))
startViews(ctx, js, conn, account, kvs, wireOf(writer), viewErrs, logger.Printf)
go func() {
select {
@@ -55,14 +55,16 @@ var readTools = []viewedTool{
}
// viewedStates are the states the views family says, each by its bucket: the six its readers read.
var viewedStates = map[string]string{
mma.StateAssignments: plc.AssignmentsBucket(),
mma.StateSeatHolders: plc.SeatHoldersBucket(),
"wants": buckets.Wants(),
assign.FindingsState: assign.FindingsBucket(),
"asks": buckets.Asks(),
"differences": buckets.Differences(),
copiesState: copiesBucket(),
func viewedStates() map[string]string {
return map[string]string{
mma.StateAssignments: plc.AssignmentsBucket(),
mma.StateSeatHolders: plc.SeatHoldersBucket(),
"wants": buckets.Wants(),
assign.FindingsState: assign.FindingsBucket(),
"asks": buckets.Asks(),
"differences": buckets.Differences(),
copiesState: copiesBucket(),
}
}
// viewTools are the assigner's first-view and read tools, reading only its own states, so they answer as soon as its
@@ -94,11 +96,11 @@ func startViews(ctx context.Context, js jetstream.JetStream, nc process.Subscrib
logf("%v: its readers ask its first view at each change until the assigner starts again", err)
}
}
if kv := kvs[viewedStates[state]]; kv != nil {
if kv := kvs[viewedStates()[state]]; kv != nil {
start(kv)
continue
}
process.AwaitBucket(ctx, js, nc, viewedStates[state], "its changes are not said on the views family", logf).Ready(start)
process.AwaitBucket(ctx, js, nc, viewedStates()[state], "its changes are not said on the views family", logf).Ready(start)
}
})
}