mesh-knowledge: review every proposal in a judgement of its own, and serve no review verb (hq issue 425, ADR 0290 as updated)
mesh/merge-gate pass: builds mesh-knowledge → novox; no bus step; every machine composes with the change as it did without (4 of 4 compose)
mesh/repo-check pass: its merge-check.sh passed, each part in its toolchain: merge-check.sh (go), merge-check-typescript.sh (typescript)
mesh/delivery superseded: a newer head of the same pull request

The mesh proves which machine called, not which agent on it (hq issue 365), so a review verb could not tell a
reviewer from the author. Each version proposed is now judged by claude-code.claude_code_judge in a separate
call that sees only the record, the records it links and the rules: approve accepts (or asks the operator for a
needs-operator record), changes keeps it proposed with the findings for its author, and a judgement that cannot
be had or read leaves it proposed, says so, and never counts as approval.
This commit is contained in:
2026-10-11 12:06:18 +02:00
parent 300406e0dd
commit ebba63d71f
14 changed files with 743 additions and 315 deletions
@@ -1,7 +1,7 @@
package main
// A record that needs the operator (novox/hq ADR 0290 rule 4, to-be 55 §5): once an independent review approves
// it, the operator is asked on the router with Approve and Decline, both at the level approve, so only a channel
// A record that needs the operator (novox/hq ADR 0290 rule 4, to-be 55 §5): once the knowledge base's own review
// approves it, the operator is asked on the router with Approve and Decline, both at the level approve, so only a channel
// that proves who answered can carry either (ADR 0259, as claude-code's proposals ask it, ADR 0274). Each option
// binds the act it authorises: this record, this version's digest. The knowledge base accepts the record only on
// the router's warrant for Approve, read back from the router's own record of the ask (which only the router
@@ -90,7 +90,7 @@ func composeAsk(r *Record, a *OperatorAsk) asks.Ask {
name := r.Key().String()
headline := "Accept " + name + "?"
var b strings.Builder
fmt.Fprintf(&b, "%s was proposed by %s and approved by an independent review. Its author says it needs your approval before it holds.", name, r.Author)
fmt.Fprintf(&b, "%s was proposed by %s and approved by the knowledge base's own review. Its author says it needs your approval before it holds.", name, r.Author)
if shown(r.Title) {
fmt.Fprintf(&b, "\n\nIts title: %s.", strings.TrimSuffix(r.Title, "."))
}
@@ -130,32 +130,48 @@ func newAskID(r *Record) string {
return fmt.Sprintf("kb-%s-%d-%s", r.Kind, r.Number, hex.EncodeToString(b[:]))
}
// askOperator asks the operator to approve a reviewed record, and keeps the ask with it.
func (k *KB) askOperator(ctx context.Context, held *Entry, w *Record, by string) (*Reviewed, error) {
if k.Asks == nil {
return nil, fmt.Errorf("%s needs the operator, and the operator cannot be asked from here; it stays proposed", w.Key())
}
// askOperator asks the operator to approve a record the knowledge base's review approved, and keeps the ask with
// it. The caller holds the write lock. An ask that could not be published is taken back, and the review is asked
// again after a pause: the record stays proposed.
func (k *KB) askOperator(ctx context.Context, held *Entry, w *Record, by string) (string, error) {
version := held.CurrentVersion
if held.Pending != nil {
version = held.PendingVersion
}
unasked := func(why string) (string, error) {
w.Ask = nil
w.Judging = &Judging{State: JudgingFailed, Tries: 1, Reason: why, At: k.now()}
said := "approved by the knowledge base's review, and " + why + "; it stays proposed and is reviewed again"
e, err := k.Store.Get(ctx, w.Key())
if err != nil || e == nil {
return "", fmt.Errorf("%s: %s, and that could not be kept (%v)", w.Key(), said, err)
}
if err := k.Store.Save(ctx, Version{By: ReviewBy, At: k.now(), Why: said, Record: w, Insight: e.Pending != nil},
e.Pending == nil, false, e.Revision); err != nil {
return "", fmt.Errorf("%s: %s, and that could not be kept (%v)", w.Key(), said, err)
}
k.emit(EventReviewed, w, ReviewBy, said, e.Versions+1)
return w.Key().String() + ": " + said, nil
}
if k.Asks == nil {
return unasked("the operator cannot be asked from here")
}
oa := &OperatorAsk{ID: newAskID(w), At: k.now(), Version: version, Said: AskWaiting}
ask := composeAsk(w, oa)
if err := ask.Check(k.now()); err != nil {
return nil, fmt.Errorf("the ask for %s could not be made (%v); it stays proposed", w.Key(), err)
return unasked(fmt.Sprintf("the ask could not be made (%v)", err))
}
w.Ask = oa
if err := k.Store.Save(ctx, Version{By: by, At: k.now(), Why: "reviewed: approved; the operator is asked", Record: w, Insight: held.Pending != nil},
held.Pending == nil, false, held.Revision); err != nil {
return nil, fmt.Errorf("the review could not be kept (%v); the operator was not asked", err)
return "", fmt.Errorf("%s: the review could not be kept (%v); the operator was not asked", w.Key(), err)
}
k.emit(EventReviewed, w, by, "approved; the operator is asked", held.Versions+1)
if err := k.Asks.Publish(asks.AskSubject(Module), ask, ask.ID); err != nil {
k.logf("[mesh-knowledge] the ask for %s could not be published: %v", w.Key(), err)
return nil, fmt.Errorf("the review is kept, and the operator could not be asked (%v): %s stays proposed; review it again to ask again", err, w.Key())
return unasked(fmt.Sprintf("the operator could not be asked (%v)", err))
}
return &Reviewed{Record: w.Key().String(), Verdict: VerdictApprove, Status: StatusProposed,
Says: fmt.Sprintf("%s needs the operator: asked on a channel that proves who answers (%q). It is accepted only on the operator's Approve; until then nothing of it is in force.", w.Key(), ask.Headline)}, nil
return fmt.Sprintf("%s needs the operator: asked on a channel that proves who answers (%q). It is accepted only on the operator's Approve; until then nothing of it is in force.", w.Key(), ask.Headline), nil
}
// routerRecord is the router's record of one ask, as far as this module reads it.
@@ -235,7 +251,7 @@ func (k *KB) decide(ctx context.Context, e *Entry, w *Record, warrant asks.Warra
case OptionApprove:
w = w.Clone()
w.Ask.Said, w.Ask.Warrant = AskApproved, warrant.Says()
r, err := k.accept(ctx, e, w, "the operator", "accepted on the operator's Approve after an independent review", "warrant: "+warrant.Says())
r, err := k.accept(ctx, e, w, "the operator", "accepted on the operator's Approve after the knowledge base's review", "warrant: "+warrant.Says())
if err != nil {
return err.Error()
}