mesh-issues and mesh-knowledge: milestones are records of the issue tracker, and progress reads them (ADR 0493 §1 to §4, issue 1781)
mesh/delivery merged: source.main moved to novox/mesh-catalog@5a4ac4991395
mesh/delivery-group group feat/1781-milestone-records merged: every member is merged
mesh/check checking 76e4ec4dc680 on 26908a89506f | novox/mesh-catalog#506 in group feat/1781-milestone-records

mesh-issues keeps each design's milestone in the state milestones (history 5), says milestone-set and
milestone-moved, and serves milestones, milestone-set and milestone-move. An issue's milestone is its own link
of kind milestone, so at most one milestone per issue is checked inside the issue's own write; kind commit
links a fixing commit. The triage links no milestone, pull request or commit. import with milestones=N seeds
a design's table once. mesh-knowledge's progress reads issue-tracker.milestones and its table parse is gone.

Squashed from four commits so the branch history does not carry a compiled bundle that was committed by
mistake (6 MB); the path is now in .gitignore.
This commit is contained in:
2026-10-26 18:42:51 +01:00
parent 26908a8950
commit 76e4ec4dc6
24 changed files with 2912 additions and 196 deletions
@@ -45,8 +45,10 @@ type seatsWorld struct {
mu sync.Mutex
rows map[int]json.RawMessage
linked map[string][]int
asked map[string]int
files map[string]json.RawMessage
// milestones is the tracker's milestone records (issue 1781).
milestones json.RawMessage
asked map[string]int
files map[string]json.RawMessage
}
func newSeatsWorld(t *testing.T) *seatsWorld {
@@ -61,6 +63,7 @@ func newSeatsWorld(t *testing.T) *seatsWorld {
_ = json.Unmarshal(r, &n)
s.rows[n.Number] = r
}
s.milestones = readFixture(t, "tracker-milestones-47.json")
for _, f := range []string{"deliveries.json", "groups.json", "show-car-hunter-2.json"} {
s.files[f] = readFixture(t, f)
}
@@ -86,9 +89,15 @@ func (s *seatsWorld) ask(key string, body any) (json.RawMessage, error) {
Linked string `json:"linked"`
Number int `json:"number"`
ID string `json:"id"`
Design int `json:"design"`
}
_ = json.Unmarshal(raw, &a)
switch key {
case MilestonesVerb:
if a.Design != 0 && a.Design != 47 {
return json.RawMessage(`{"milestones": []}`), nil
}
return s.milestones, nil
case "seat:issue-tracker.list":
numbers := a.Numbers
if a.Linked != "" {
@@ -131,31 +140,37 @@ func (c *countingRecords) Read(p string) (string, string, error) {
return content, c.commit, err
}
// 1947/AC2: the milestone table of design 47, as hq holds it, read into milestones with their issues, and what the
// prose does not say for certain said as warnings.
func TestTheDesignReaderReadsTheMilestoneTable(t *testing.T) {
// 1947/AC2, as issue 1781 changed it: a design's title, state and decisions are hq's; its milestones are the issue
// tracker's records, ordered as its table, an id found with spaces or hyphens, and a closed one holding no issue done.
func TestADesignsMilestonesAreTheTrackersRecords(t *testing.T) {
content, _, err := progressRecords().Read(DesignsFolder + "/47-delivery-from-commit-to-delivered.md")
if err != nil {
t.Fatal(err)
}
d := parseDesign(DesignsFolder+"/47-delivery-from-commit-to-delivered.md", content)
if d.Number != 47 || d.Title != "Delivery: from a commit to delivered" || d.Status != "in-progress" || !contains(d.Decisions, "ADR 0276") {
t.Fatalf("design %d %q %q %v", d.Number, d.Title, d.Status, d.Decisions)
if d.Number != 47 || d.Title != "Delivery: from a commit to delivered" || d.Status != "in-progress" || !contains(d.Decisions, "ADR 0276") ||
len(d.Milestones) != 0 {
t.Fatalf("design %d %q %q %v, %d milestones read from hq", d.Number, d.Title, d.Status, d.Decisions, len(d.Milestones))
}
if len(d.Milestones) != 29 {
t.Fatalf("%d milestones", len(d.Milestones))
seats := newSeatsWorld(t)
k := &KB{Seats: seats.ask}
ds, err := k.withMilestones([]*Design{d}, 47)
if err != nil {
t.Fatal(err)
}
if len(ds[0].Milestones) != 29 || len(d.Milestones) != 0 || seats.asked[MilestonesVerb] != 1 {
t.Fatalf("%d milestones; the cached design holds %d", len(ds[0].Milestones), len(d.Milestones))
}
for _, c := range []struct {
id string
want []int
}{
{"1", []int{973, 525}},
{"2b", []int{1025, 1019}},
{"R6", []int{1942, 1945, 1943, 1944, 1946, 1906, 1130}},
{"r4d", []int{}},
{"3 fix", []int{1082, 1049, 1047, 1083, 1079, 1084}},
} {
m := d.milestone(c.id)
m := ds[0].milestone(c.id)
if m == nil {
t.Fatalf("no milestone %s", c.id)
}
@@ -163,25 +178,10 @@ func TestTheDesignReaderReadsTheMilestoneTable(t *testing.T) {
t.Errorf("milestone %s: %v, want %v", c.id, m.Issues, c.want)
}
}
if r4a := d.milestone("R4a"); len(r4a.Issues) != 14 || !containsInt(r4a.Issues, 1360) {
t.Errorf("R4a's range 1353 to 1364 read as %v", r4a.Issues)
}
warned := strings.Join(d.Warnings, "\n")
for _, w := range []string{"issue 1209 is in milestones R3b and R3c", "issue 971 is in milestones 6 and R4c",
`"1353 to 1364" is a range in words, read as the 12 issues`, "milestone R4d names no issue"} {
if !strings.Contains(warned, w) {
t.Errorf("no warning %q in\n%s", w, warned)
}
}
// Design 57's range with an exception, and a design with no milestone table.
content, _, _ = progressRecords().Read(DesignsFolder + "/57-building-config-and-provisioning.md")
d57 := parseDesign(DesignsFolder+"/57-building-config-and-provisioning.md", content)
if m := d57.milestone("1"); m == nil || containsInt(m.Issues, 659) || !containsInt(m.Issues, 678) || !containsInt(m.Issues, 685) {
t.Errorf("design 57 milestone 1: %+v", d57.Milestones)
}
content, _, _ = progressRecords().Read(DesignsFolder + "/53-the-issue-tracker.md")
if d53 := parseDesign(DesignsFolder+"/53-the-issue-tracker.md", content); len(d53.Milestones) != 0 || d53.Status != "in-progress" {
t.Errorf("design 53: %+v", d53.Milestones)
closed := &Design{Milestones: []Milestone{{ID: "6", Status: "closed", Reason: "folded into release 4"}, {ID: "R4d", Status: "open"}}}
items, _ := milestoneItems(closed, nil, nil)
if items[0].State != StateDone || items[1].State != StateWaiting {
t.Fatalf("%+v", items)
}
}
@@ -207,8 +207,8 @@ func TestDesignsAreReadAgainOnlyWhenHqMoves(t *testing.T) {
if rec.reads != 3 {
t.Fatalf("read %d documents for the mesh, want 3", rec.reads)
}
if !strings.Contains(p.Tree, "3 designs in progress, 2 with milestones") || !strings.Contains(p.Tree, "design 47 · Delivery: from a commit to delivered") ||
!strings.Contains(p.Tree, "1 designs in progress name no milestones (issue 845): 53") {
if !strings.Contains(p.Tree, "3 designs in progress, 1 with milestones") || !strings.Contains(p.Tree, "design 47 · Delivery: from a commit to delivered") ||
!strings.Contains(p.Tree, "2 designs in progress name no milestones (issue 845): 53, 57") {
t.Fatalf("mesh:\n%s", p.Tree)
}
for range 2 {
@@ -303,7 +303,7 @@ func TestProgressOfADesignMinimalAndDetailed(t *testing.T) {
t.Fatal(err)
}
raw, _ := json.Marshal(p)
if len(raw) > DefaultBound || p.Detail != DetailMinimal || !strings.Contains(p.Source, "issue 1781") {
if len(raw) > DefaultBound || p.Detail != DetailMinimal || !strings.Contains(p.Source, "the issue tracker's milestone records of design 47") {
t.Fatalf("%d bytes, %s, %s", len(raw), p.Detail, p.Source)
}
if seats.asked["seat:issue-tracker.list"] != 1 || seats.asked["seat:mesh-delivery.deliveries"] != 0 || seats.asked["seat:issue-tracker.get"] != 0 {
@@ -316,7 +316,7 @@ func TestProgressOfADesignMinimalAndDetailed(t *testing.T) {
if !strings.HasPrefix(lines[0], "✗ design 47 · Delivery: from a commit to delivered — ") {
t.Fatalf("first line %q", lines[0])
}
for _, want := range []string{"✗ R6 4/7 1945 fixing since", "✗ 3 fix 0/1 1049 fixing, worker fix-chain-cat@shanks stale since"} {
for _, want := range []string{"✗ R6 4/7 1945 fixing since", "✗ 3-fix 0/1 1049 fixing, worker fix-chain-cat@shanks stale since"} {
if !strings.Contains(p.Tree, want) {
t.Errorf("no %q in\n%s", want, p.Tree)
}
@@ -346,7 +346,7 @@ func TestProgressOfADesignMinimalAndDetailed(t *testing.T) {
if raw, _ := json.Marshal(small); len(raw) > LeastBound || !strings.Contains(small.Cut, "raise bound") {
t.Fatalf("%d bytes within %d; cut %q", len(raw), LeastBound, small.Cut)
}
for _, bad := range []ProgressAsk{{Of: "design"}, {Of: "milestone 47/R99"}, {Of: "design 47", Detail: "full"}} {
for _, bad := range []ProgressAsk{{Of: "design"}, {Of: "milestone 47/R99"}, {Of: "design 47", Detail: "full"}, {Of: "design 57"}} {
if _, err := k.Progress(bad); err == nil {
t.Errorf("%+v was answered", bad)
}