mesh-issues: a take-over note records who acted, not the worker named; tests for the remaining rules (hq issue 399)
mesh/merge-gate pass: builds mesh-issues → 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 delivered
mesh/delivery-group group feat/399-fixing-status merged: every member is merged

The note's by is who acted as the runtime proves it (ADR 0275 §5); the
note's text names both workers. Tests for a resolved issue corrected, link
and set keeping the worker current, and a take-over reason with a secret's
shape. The ready-to-verify note says an issue resolves from fixing.
This commit is contained in:
jochen
2026-10-10 21:10:36 +02:00
parent 11afde55d6
commit a73b04843d
4 changed files with 57 additions and 3 deletions
@@ -91,7 +91,7 @@ func TestATakeOverNeedsAReasonAndIsNoted(t *testing.T) {
is, _ := h.Get(n)
if is.Worker.By != "jochen@shanks" || m.TookOverFrom != "fix-a@g14" || len(is.Notes) != 1 ||
!strings.Contains(is.Notes[0].Text, "from fix-a@g14") || !strings.Contains(is.Notes[0].Text, "the operator finishes it by hand") ||
is.Notes[0].By != "jochen@shanks" {
is.Notes[0].By != Unproven {
t.Fatalf("worker %+v, notes %+v, answer %+v", is.Worker, is.Notes, m)
}
ev := h.said()
@@ -244,3 +244,56 @@ func TestTheMoveVerbTakesByAndTakeOver(t *testing.T) {
}
}
}
// A resolved issue may still have what it holds corrected: resolved to resolved is not refused as "not from fixing".
func TestAResolvedIssueMayBeCorrected(t *testing.T) {
h := newHarness(t)
n := h.open(t, "x", "hq")
h.fixing(t, n)
if _, err := h.Move(MoveAsk{Number: n, Status: StatusResolved, FixedBy: []string{"hq#1"}}); err != nil {
t.Fatal(err)
}
if _, err := h.Move(MoveAsk{Number: n, Status: StatusResolved, FixedBy: []string{"hq#1", "hq#2"}}); err != nil {
t.Fatalf("a correction of a resolved issue: %v", err)
}
if is, _ := h.Get(n); len(is.FixedBy) != 2 {
t.Fatalf("%+v", is.FixedBy)
}
}
// A caller's link and set keep the worker current, as a note does (ADR 0283 §4).
func TestALinkAndASetKeepTheWorkerCurrent(t *testing.T) {
for _, act := range []string{"link", "unlink", "set"} {
t.Run(act, func(t *testing.T) {
h := newHarness(t)
now := clocked(h)
n := h.open(t, "x", "hq")
other := h.open(t, "y")
if act == "unlink" {
if _, err := h.Link(LinkAsk{Number: n, Kind: LinkRelatesTo, Target: keyOf(other)}); err != nil {
t.Fatal(err)
}
}
if _, err := h.Move(MoveAsk{Number: n, Status: StatusFixing, By: "fix-a@g14"}); err != nil {
t.Fatal(err)
}
*now = now.Add(20 * time.Hour)
var err error
switch act {
case "link":
_, err = h.Link(LinkAsk{Number: n, Kind: LinkRelatesTo, Target: keyOf(other)})
case "unlink":
_, err = h.Link(LinkAsk{Number: n, Kind: LinkRelatesTo, Target: keyOf(other), Remove: true})
case "set":
_, err = h.Set(SetAsk{Number: n, Severity: "minor"})
}
if err != nil {
t.Fatal(err)
}
*now = now.Add(10 * time.Hour) // 30 h after the start, 10 h after the act
if _, err := h.Move(MoveAsk{Number: n, Status: StatusFixing, By: "fix-b@ace"}); err == nil {
t.Fatalf("the %s did not keep the worker current", act)
}
})
}
}