mesh-issues: an issue says who works on it, and resolves only from fixing (hq issue 399)
mesh/delivery-group group feat/399-fixing-status checking: 0 of 2 member(s) ready
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 superseded: a newer head of the same pull request
mesh/delivery-group group feat/399-fixing-status checking: 0 of 2 member(s) ready
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 superseded: a newer head of the same pull request
Two agents could start on one issue without seeing each other, and an issue could be resolved without anyone having said they started its fix. A move to diagnosing or fixing now names by, the worker as who@node; get and list show the worker with since and stale; another worker is refused while it is current unless take-over says why (noted); a worker untouched for worker-stale-after (24h) may be taken over from without a reason. Resolved is reached only from fixing. The moved event carries by, since and caller. Fixing counts as not closed for the triage and the duplicate check. hq ADR 0283.
This commit is contained in:
@@ -44,6 +44,9 @@ type Settings struct {
|
||||
// StuckAfter is how long a fix may be merged and not delivered before it is said stuck (ADR 0281), as a
|
||||
// duration such as 2h; DefaultStuckAfter when empty.
|
||||
StuckAfter string `json:"stuck-after,omitempty"`
|
||||
// WorkerStaleAfter is how long an issue's worker stays current with nothing done on it (ADR 0283 §2), as a
|
||||
// duration such as 24h; DefaultWorkerStaleAfter when empty.
|
||||
WorkerStaleAfter string `json:"worker-stale-after,omitempty"`
|
||||
}
|
||||
|
||||
func readSettings(path string) (Settings, error) {
|
||||
@@ -335,7 +338,8 @@ func Tools(t *Tracker) []stdio.Tool {
|
||||
}},
|
||||
{Name: Seat + ".get",
|
||||
Description: "One issue whole, by its number: title, status, severity, what it needs, report, who opened it " +
|
||||
"and when, the owners it is located in, what fixed it and whether that is delivered, its notes and its " +
|
||||
"and when, the owners it is located in, who works on it and since when (worker, and worker-stale when " +
|
||||
"nobody did anything on it for a day), what fixed it and whether that is delivered, its notes and its " +
|
||||
"links; the issues it waits for, those that depend on it (needed-by), and whether it is ready; and " +
|
||||
"whether its fix is delivered, as the delivery last said it (merged, held and why, delivered).",
|
||||
Input: schema([]string{"number"}, map[string]any{"number": number("the issue's number")}),
|
||||
@@ -355,7 +359,9 @@ func Tools(t *Tracker) []stdio.Tool {
|
||||
"those at one status (" + statuses + "), located in one owner, at one severity, needing one thing, " +
|
||||
"ready or not, or whose title or report holds a phrase. An agent looking for work asks severity minor, " +
|
||||
"needs none, ready. An issue is ready when everything it depends on is closed, or resolved with its fix " +
|
||||
"delivered. Each row says whether its fix is delivered. Answers what is open in one call.",
|
||||
"delivered. Each row says whether its fix is delivered, and, for an issue at diagnosing or fixing, who " +
|
||||
"works on it (worker) since when, and stale when nobody did anything on it for a day, so it may be " +
|
||||
"taken over. Answers what is open in one call.",
|
||||
Input: schema(nil, map[string]any{
|
||||
"status": map[string]any{"type": "string", "enum": Statuses, "description": "only issues at this status"},
|
||||
"owner": text("only issues located in this owner, such as mesh-controller"),
|
||||
@@ -404,11 +410,15 @@ func Tools(t *Tracker) []stdio.Tool {
|
||||
}},
|
||||
{Name: Seat + ".move",
|
||||
Description: "Change an issue's status — " + statuses + " — with what that status needs, under the " +
|
||||
"development cycle's rules: located needs located-in, owners on the registered list; resolved needs " +
|
||||
"located-in and fixed-by (the pull requests or commits), and an issue in the mesh's core also replay " +
|
||||
"(the replay's id, such as R361) or replay-none (why no replay is possible); wontfix needs a reason. " +
|
||||
"A move to the status it has changes only what it holds, such as naming the fix while it stays located. " +
|
||||
"A refused move changes nothing and says which rule refused it.",
|
||||
"development cycle's rules. Move an issue to diagnosing or fixing when you start work on it, with by: " +
|
||||
"who works on it and its node, as who@node (such as fix-399@g14); the issue shows it until it moves on. " +
|
||||
"Refused while someone else works on it, naming them, unless take-over says why (noted on the issue); a " +
|
||||
"worker who did nothing on it for a day may be taken over from without a reason. located needs located-in, owners on " +
|
||||
"the registered list; resolved is reached only from fixing and needs located-in and fixed-by (the pull " +
|
||||
"requests or commits), and an issue in the mesh's core also replay (the replay's id, such as R361) or " +
|
||||
"replay-none (why no replay is possible); wontfix needs a reason. A move to the status it has changes " +
|
||||
"only what it holds, such as naming the fix while it stays fixing. A refused move changes nothing and " +
|
||||
"says which rule refused it.",
|
||||
Input: schema([]string{"number", "status"}, map[string]any{
|
||||
"number": number("the issue's number"),
|
||||
"status": map[string]any{"type": "string", "enum": Statuses, "description": "the status it moves to"},
|
||||
@@ -418,9 +428,11 @@ func Tools(t *Tracker) []stdio.Tool {
|
||||
"replay": text("for a core issue resolved: the replay's id in mesh-lab's replays register, such as R361"),
|
||||
"replay-none": text("for a core issue resolved: why no replay is possible"),
|
||||
"reason": text("for wontfix: why it will not be fixed"),
|
||||
"by": text("for diagnosing and fixing: who works on it and its node, as who@node, such as fix-399@g14 or jochen@shanks"),
|
||||
"take-over": text("for diagnosing and fixing, when someone else works on it: why you take it over"),
|
||||
}),
|
||||
Run: func(m map[string]any) (any, error) {
|
||||
a, err := readArgs("move", m, "number", "status", "located-in", "fixed-by", "amended-design", "replay", "replay-none", "reason")
|
||||
a, err := readArgs("move", m, "number", "status", "located-in", "fixed-by", "amended-design", "replay", "replay-none", "reason", "by", "take-over")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
@@ -431,7 +443,8 @@ func Tools(t *Tracker) []stdio.Tool {
|
||||
for _, f := range []struct {
|
||||
k string
|
||||
p *string
|
||||
}{{"status", &ask.Status}, {"replay", &ask.Replay}, {"replay-none", &ask.ReplayNone}, {"reason", &ask.Reason}} {
|
||||
}{{"status", &ask.Status}, {"replay", &ask.Replay}, {"replay-none", &ask.ReplayNone}, {"reason", &ask.Reason},
|
||||
{"by", &ask.By}, {"take-over", &ask.TakeOver}} {
|
||||
if *f.p, err = a.str(f.k); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user