Held writer: a part names the keys it cannot judge yet in its findings-stated's pending
views.HeldWriter gains Pend and Judged: a key pended is named, with its since and bound, in every statement until the part judges it, a key pended again keeping its first since. The tool runner pends an acted, unrecorded ask's call-unanswered at its start until its warranted is made again. Builds: design 46 7-approval-mark §16; design 47 G §384 Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
This commit is contained in:
+28
-1
@@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"sort"
|
||||
"sync"
|
||||
)
|
||||
|
||||
@@ -20,6 +21,9 @@ type HeldWriter[F, C, S, A any] struct {
|
||||
started bool
|
||||
pending map[string]F // written before Start, written through the writer at Start
|
||||
cleared map[string][4]string // cleared before Start, cleared through the writer at Start
|
||||
// pends are the keys the part cannot judge yet since its start (design 47 G §384): a kept call it has not yet made
|
||||
// again, named in every statement until the part judges it.
|
||||
pends map[string]PendingKey
|
||||
}
|
||||
|
||||
// NewHeldWriter makes the writer for cfg, whose Observe is none (a given Observe is refused): the findings that stand in
|
||||
@@ -32,7 +36,7 @@ func NewHeldWriter[F, C, S, A any](cfg WriterConfig[F, C, S, A]) (*HeldWriter[F,
|
||||
if cfg.State == nil {
|
||||
return nil, errors.New("a finding writer needs the state `findings`")
|
||||
}
|
||||
h := &HeldWriter[F, C, S, A]{held: map[string]F{}}
|
||||
h := &HeldWriter[F, C, S, A]{held: map[string]F{}, pends: map[string]PendingKey{}}
|
||||
h.state, h.pending, h.cleared = cfg.State, map[string]F{}, map[string][4]string{}
|
||||
cfg.Observe = func(context.Context) (Observed[F], error) {
|
||||
h.mu.Lock()
|
||||
@@ -41,6 +45,10 @@ func NewHeldWriter[F, C, S, A any](cfg WriterConfig[F, C, S, A]) (*HeldWriter[F,
|
||||
for _, f := range h.held {
|
||||
o.Findings = append(o.Findings, f)
|
||||
}
|
||||
for _, p := range h.pends {
|
||||
o.Pending = append(o.Pending, p)
|
||||
}
|
||||
sort.Slice(o.Pending, func(i, j int) bool { return o.Pending[i].Key < o.Pending[j].Key })
|
||||
return o, nil
|
||||
}
|
||||
w, err := NewWriter(cfg)
|
||||
@@ -100,6 +108,25 @@ func (h *HeldWriter[F, C, S, A]) WriteWire(ctx context.Context, finding map[stri
|
||||
return h.Write(ctx, f)
|
||||
}
|
||||
|
||||
// Pend names a key the part cannot judge yet since its start, with its since and its bound, in every statement until Judged
|
||||
// (design 47 G §384; design 46 7-approval-mark §16: an acted ask whose hand-act is not yet asked again). A key pended again
|
||||
// keeps its first since.
|
||||
func (h *HeldWriter[F, C, S, A]) Pend(p PendingKey) {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
if was, ok := h.pends[p.Key]; ok {
|
||||
p.Since = was.Since
|
||||
}
|
||||
h.pends[p.Key] = p
|
||||
}
|
||||
|
||||
// Judged ends a key's pending: the part judged it, raising or clearing its finding as it found.
|
||||
func (h *HeldWriter[F, C, S, A]) Judged(key string) {
|
||||
h.mu.Lock()
|
||||
defer h.mu.Unlock()
|
||||
delete(h.pends, key)
|
||||
}
|
||||
|
||||
// Held answers the findings the writer holds, a copy taken under its lock (design 47 G A-38), so a part reads its open findings
|
||||
// from the writer.
|
||||
func (h *HeldWriter[F, C, S, A]) Held() []F {
|
||||
|
||||
@@ -505,6 +505,12 @@ func subHeldWriterStatesWhatItHoldsFromItsOwnState(t *testing.T) {
|
||||
if err := h.Clear(ctx, "module", "seeded", "k", "no longer"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
// a key the part cannot judge yet is named in the statement's pending until judged (design 47 G §384), keeping its since
|
||||
since := time.Date(2026, 11, 12, 9, 0, 0, 0, time.UTC)
|
||||
h.Pend(views.PendingKey{Key: "machine.n1.a2.call-unanswered", Since: since, Bound: "5m"})
|
||||
h.Pend(views.PendingKey{Key: "machine.n1.a2.call-unanswered", Since: since.Add(time.Hour), Bound: "5m"})
|
||||
h.Pend(views.PendingKey{Key: "machine.n1.a3.call-unanswered", Since: since, Bound: "5m"})
|
||||
h.Judged("machine.n1.a3.call-unanswered")
|
||||
sent = nil
|
||||
if err := h.State(ctx, "a1"); err != nil {
|
||||
t.Fatal(err)
|
||||
@@ -514,6 +520,9 @@ func subHeldWriterStatesWhatItHoldsFromItsOwnState(t *testing.T) {
|
||||
len(stated.Findings) != 2 || stated.Asked != "a1" {
|
||||
t.Fatalf("the statement says %+v after %d events", stated, len(sent))
|
||||
}
|
||||
if p := stated.Pending; len(p) != 1 || p[0].Key != "machine.n1.a2.call-unanswered" || !p[0].Since.Equal(since) || p[0].Bound != "5m" {
|
||||
t.Fatalf("the statement's pending is %+v", p)
|
||||
}
|
||||
if held := h.Held(); len(held) != 2 {
|
||||
t.Fatalf("Held answers %v", held)
|
||||
} else if held[0].ID = "mutated"; len(h.Held()) != 2 {
|
||||
|
||||
Reference in New Issue
Block a user