pacman reads the node-engine's packages first and the controller's mirror per node until the lease write; compare counts only an indexer that was read, and a forge not heard is said in the row (review round 1)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
@@ -75,9 +75,8 @@ func (runtimeStore) Read(log string) ([]LogEntry, error) {
|
||||
|
||||
func (runtimeStore) Emit(event string, body any) error { return stdio.Emit(event, body) }
|
||||
|
||||
// recorder records into the hand-act log of the seat mesh-hand-acts (novox/hq ADR 0565 §11). The manifest invokes no verb
|
||||
// of the controller (issue 1953), so the SDK recorder's fall back to the controller's log, while the seat has no holder,
|
||||
// is refused by the bus and said in the answer: nothing is recorded in two logs.
|
||||
// recorder records into the hand-act log of the seat mesh-hand-acts alone (novox/hq ADR 0565 §11, issue 1953): the manifest
|
||||
// invokes no verb of the controller and the SDK recorder has no fall back to its log.
|
||||
var recorder = handacts.Recorder{Ask: stdio.Ask, LeaseAway: func() bool {
|
||||
e, err := stdio.State(LeaseRead).Get(buscompose.ControllerLeaseKey)
|
||||
var raw []byte
|
||||
|
||||
@@ -355,8 +355,11 @@ func (c *Config) compare() (*Comparison, error) {
|
||||
declaresNothing := map[string]bool{}
|
||||
for module, d := range mirror.Declared {
|
||||
if len(d.Config) == 0 {
|
||||
if _, err := c.trunkDeclarations(module); err != nil {
|
||||
declaresNothing[module] = true
|
||||
// Only an indexer that was read and holds no modules.<module>: a failed read says nothing, and the row stays.
|
||||
if key, kerr := delivery.ModulesKey(module); kerr == nil {
|
||||
if e, err := c.Store.Get(ModulesRead, key); err == nil && e == nil {
|
||||
declaresNothing[module] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -428,9 +431,11 @@ func (c *Config) compare() (*Comparison, error) {
|
||||
for _, k := range unionKeys(cands, own.Pulls) {
|
||||
a, aok := cands[k]
|
||||
b, bok := own.Pulls[k]
|
||||
if c.pullSettled(firstNonEmpty(a.Pull, b.Pull), settled) {
|
||||
isSettled, forgeNote := c.pullSettled(firstNonEmpty(a.Pull, b.Pull), settled)
|
||||
if isSettled {
|
||||
continue // a merged or closed pull request is no candidate to agree on (the operator, 2026-11-01)
|
||||
}
|
||||
before := len(diffs)
|
||||
switch {
|
||||
case !aok:
|
||||
diffs = append(diffs, Difference{What: DiffPull, Pull: b.Pull, Why: "the controller told its declarations and the indexer holds no candidate"})
|
||||
@@ -442,6 +447,9 @@ func (c *Config) compare() (*Comparison, error) {
|
||||
case declaresDigest(a.Declares) != declaresDigest(b.Declares):
|
||||
diffs = append(diffs, Difference{What: DiffPull, Pull: a.Pull, Why: "the two declare its config otherwise"})
|
||||
}
|
||||
if forgeNote != "" && len(diffs) > before {
|
||||
diffs[len(diffs)-1].Why += "; " + forgeNote // the row stays because the forge was not heard: say so in the row
|
||||
}
|
||||
}
|
||||
|
||||
// Every placed module's value on every node, resolved both ways.
|
||||
@@ -502,22 +510,22 @@ func firstNonEmpty(a, b string) string {
|
||||
|
||||
// pullSettled is whether the forge says a pull request merged or closed. Without a forge, or when it does not say, the
|
||||
// pull request counts as open, so its row stays (failure is loud).
|
||||
func (c *Config) pullSettled(pull string, memo map[string]string) bool {
|
||||
func (c *Config) pullSettled(pull string, memo map[string]string) (bool, string) {
|
||||
if c.Forge == nil || pull == "" {
|
||||
return false
|
||||
return false, ""
|
||||
}
|
||||
if v, ok := memo[pull]; ok {
|
||||
return v != ""
|
||||
return v != "" && !strings.HasPrefix(v, forgeSilent), forgeNoteOf(v)
|
||||
}
|
||||
owner, repo, n, err := parsePull(pull)
|
||||
if err != nil {
|
||||
return false
|
||||
return false, ""
|
||||
}
|
||||
open, merged, _, err := c.Forge.Pull(owner, repo, n)
|
||||
switch {
|
||||
case err != nil:
|
||||
c.logf("[mesh-config] compare: the forge does not say whether %s is open (%v); its row stays", pull, err)
|
||||
memo[pull] = ""
|
||||
memo[pull] = forgeSilent + err.Error()
|
||||
case open:
|
||||
memo[pull] = ""
|
||||
case merged:
|
||||
@@ -525,7 +533,19 @@ func (c *Config) pullSettled(pull string, memo map[string]string) bool {
|
||||
default:
|
||||
memo[pull] = "closed"
|
||||
}
|
||||
return memo[pull] != ""
|
||||
v := memo[pull]
|
||||
return v != "" && !strings.HasPrefix(v, forgeSilent), forgeNoteOf(v)
|
||||
}
|
||||
|
||||
// forgeSilent marks a memo entry for a pull request the forge could not be asked about; the rest of the entry is why.
|
||||
const forgeSilent = "forge-silent: "
|
||||
|
||||
// forgeNoteOf is the words a row carries when the forge was not heard on its pull request, or "".
|
||||
func forgeNoteOf(v string) string {
|
||||
if why, ok := strings.CutPrefix(v, forgeSilent); ok {
|
||||
return "the forge does not say whether the pull request is open (" + why + ")"
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
// normal is declarations in one encoding: a null default as none.
|
||||
|
||||
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"slices"
|
||||
"strings"
|
||||
"testing"
|
||||
@@ -92,6 +93,9 @@ func TestCompareListsEveryDifferenceAndTheTakeOverWaitsForNone(t *testing.T) {
|
||||
candidate(t, m, "novox/mesh-catalog#11", "h1", `{"dunst":{"gap":{"kind":"","type":"number","default":2}}}`)
|
||||
candidate(t, m, "novox/mesh-catalog#10", "h2", `{"dunst":{"gap":{"kind":"","type":"number","default":2}}}`)
|
||||
}, []string{"pull:novox/mesh-catalog#10"}},
|
||||
{"a forge that cannot be asked keeps the row and says why in it", func(t *testing.T, m *memStore) {
|
||||
candidate(t, m, "novox/mesh-catalog#12", "h1", `{"dunst":{"gap":{"kind":"","type":"number","default":2}}}`)
|
||||
}, []string{"pull:novox/mesh-catalog#12"}},
|
||||
{"a module no manifest names and the mirror declares nothing of", func(t *testing.T, m *memStore) {
|
||||
m.assign(t, "g14", "mesh-wireguard")
|
||||
m.mirror(t, MirrorDeclaredRead, "mesh-wireguard", `{"module":"mesh-wireguard","settings":{}}`)
|
||||
@@ -100,6 +104,9 @@ func TestCompareListsEveryDifferenceAndTheTakeOverWaitsForNone(t *testing.T) {
|
||||
for _, tc := range cases {
|
||||
c, m, r := anAgreeingMesh(t)
|
||||
c.Forge = &standForge{state: map[string][2]bool{"novox/mesh-catalog#11": {false, true}}}
|
||||
if strings.Contains(tc.name, "forge that cannot be asked") {
|
||||
c.Forge = &standForge{err: errors.New("forge down")}
|
||||
}
|
||||
tc.change(t, m)
|
||||
cmp, err := c.Compare()
|
||||
if err != nil {
|
||||
@@ -112,6 +119,9 @@ func TestCompareListsEveryDifferenceAndTheTakeOverWaitsForNone(t *testing.T) {
|
||||
if d.Why == "" {
|
||||
t.Errorf("%s: a difference without its reason: %+v", tc.name, d)
|
||||
}
|
||||
if strings.Contains(tc.name, "forge that cannot be asked") && !strings.Contains(d.Why, "forge down") {
|
||||
t.Errorf("%s: the row does not say the forge was not heard: %q", tc.name, d.Why)
|
||||
}
|
||||
}
|
||||
a, err := c.TakeOver(Call{Why: "compare is empty", Caller: "person.jochen"})
|
||||
if len(tc.want) > 0 {
|
||||
|
||||
Reference in New Issue
Block a user