mesh-issues: triage every new issue — severity, needs, suggested owner, dependencies — and say an issue ready when what it depends on is delivered (hq ADR 0279)
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/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
The operator asked for the judgement that already reads the backlog to fill what an issuer cannot know, and for dependencies between issues, an issue being workable only once what it waits for is on the machines. The triage fills only empty values, adds links and removes none; readiness follows mesh-delivery's own events.
This commit is contained in:
@@ -23,7 +23,8 @@ what it refuses.
|
||||
| `note` | `number`, `text` | appends a note; a note is never edited |
|
||||
| `link` | `number`, `kind`, `target`, optionally `remove` | adds or removes a typed link |
|
||||
| `import` | optionally `dry-run`, `commit` | hq's issue folders, read through the records module, each written as an issue under its own number; see below |
|
||||
| `groom` | optionally `pass`, `confirm` | the duplicate check over the backlog: without arguments a dry run in the background, answering its pass id; with `pass` its progress and findings; with `confirm` and `pass` exactly that pass's findings applied, each checked again; see below |
|
||||
| `set` | `number`, any of `severity`, `needs`, `suggested-owner` | changes them as a person decides |
|
||||
| `groom` | optionally `pass`, `confirm` | the triage over the backlog: without arguments a dry run in the background, answering its pass id; with `pass` its progress and findings; with `confirm` and `pass` exactly that pass's findings applied, each checked again; see below |
|
||||
|
||||
**The cycle's rules, at the write** (hq playbook 03, which `00-META/checks/cycle.py` enforced on the
|
||||
folders until the import): a status is one of `open`,
|
||||
@@ -36,36 +37,49 @@ needs a `reason`. A refused change changes nothing and says which rule refused i
|
||||
tracker like any other: the folder holds its narrative, the tracker its status. Until the import of
|
||||
slice 3 ran, such an issue kept its status in the folder and `move` refused it; the import filled it.
|
||||
|
||||
## The duplicate check (hq ADR 0278)
|
||||
## The triage (hq ADR 0278, ADR 0279)
|
||||
|
||||
Every issue opened is checked by the module itself: it consumes its own `mesh-issues.opened` event, and for an
|
||||
Every issue opened is triaged by the module itself: it consumes its own `mesh-issues.opened` event, and for an
|
||||
issue still at `open` asks the agent on its node — `claude-code.claude_code_judge@<node>`, which runs the agent
|
||||
with no tools under the node's licence — two questions: a shortlist of at most five older issues by their titles,
|
||||
then a verdict on the reports (`duplicate`, `related` or `none`, whether it is certain, and why). Only issues at
|
||||
`open`, `diagnosing` or `located` that are older than the new one are offered; a resolved or wontfix issue is
|
||||
never offered, linked or noted.
|
||||
then, always, a judgement on the reports: whether it repeats one (`duplicate`, `related` or `none`, whether it is
|
||||
certain, and why), its **severity** (critical, major, minor), what it **needs** (none, decision, operator), a
|
||||
suggested owner when it names none, and the shortlisted issues it **depends on** or **relates to**, each with a
|
||||
one-line reason. Only issues at `open`, `diagnosing` or `located` that are older than the new one are offered.
|
||||
|
||||
| verdict | done, through the module's own `note`, `link` and `move`, each recorded as by `duplicate-check` |
|
||||
|---|---|
|
||||
| `duplicate`, certain | the verdict noted on the new issue; linked `duplicates` to the older; its title and report noted on the older; moved to `wontfix`, reason "duplicate of N" |
|
||||
| `related`, or `duplicate` not certain | the verdict noted; linked `relates-to`; noted on the older; nothing moves |
|
||||
| `none` | one note: checked against so many issues |
|
||||
The judgement is kept on the issue (`triage`) and said as the event `triaged` before anything else, then applied
|
||||
through the module's own `note`, `set`, `link` and `move`, each recorded as by `triage` and each only when not
|
||||
done yet:
|
||||
|
||||
The older issue never moves. The verdict note is written first, its first line in a fixed form (`Duplicate
|
||||
check: duplicate of N.`), so a second delivery of the event, or the backlog's pass, does only the steps not yet
|
||||
done and never judges again. A judgement that fails — no answer, a late one, an answer outside the shape, an
|
||||
issue not offered — leaves one note saying why, and the event is not taken: the bus offers it again, and after
|
||||
its fifth delivery the controller raises `max-deliveries` on the module's consumer and keeps the event for a
|
||||
person to deliver again.
|
||||
1. one note saying the whole judgement, a line per value with its reason; where the issuer gave a severity or
|
||||
needs the triage disagrees with, the line says so and the given value stands;
|
||||
2. each empty value filled — never one a person gave;
|
||||
3. each `depends-on` and `relates-to` link added, unless it is there, would close a cycle, or its target is
|
||||
resolved or wontfix; the older issue gains a note;
|
||||
4. a certain duplicate: linked `duplicates`, its title and report noted on the older, moved to `wontfix`
|
||||
"duplicate of N" last. The older issue never moves.
|
||||
|
||||
`groom` runs the same judgement over every issue not resolved and not yet checked, oldest first, against the
|
||||
older ones not resolved and not found a duplicate in the same pass. It writes only the pass, in the state
|
||||
`grooming` (the last pass, one key), and applies that pass's findings on `confirm` — never a fresh judgement.
|
||||
A finding whose issues have moved on is skipped and said. It adds no "none" note to the backlog.
|
||||
A second delivery of the event finds the kept judgement and finishes what is missing without judging again. A
|
||||
judgement that fails leaves one note, and the event is not taken: after its fifth delivery the controller raises
|
||||
`max-deliveries` on the module's consumer. Notes the duplicate check of ADR 0278 wrote as `duplicate-check` are
|
||||
still read as that issue's verdict.
|
||||
|
||||
The tracker asks one judgement at a time; the pass waits while a new issue's check is waiting, and one verdict is
|
||||
applied at a time. A check may take up to a minute (two judgements of at most 25 seconds each), which the tool
|
||||
runner allows a handler while keeping its event alive (hq issue 387).
|
||||
**Ready.** An issue is ready when it is not resolved or wontfix and every issue it depends on is wontfix, or
|
||||
resolved with every pull request its `fixed-by` names (`<repository>#<number>`) delivered. The module consumes
|
||||
`mesh-delivery.transition` and marks a pull request delivered on every issue naming it; at its own `moved` to
|
||||
resolved it asks `seat:mesh-delivery.checks` once for what it has not heard. An issue made ready gains a note and
|
||||
the event `ready`. `get` answers `waits-for`, `needed-by` and `ready`; `list` filters on `severity`, `needs` and
|
||||
`ready` — an agent looking for work asks `severity=minor`, `needs=none`, `ready=true`. `set` changes severity,
|
||||
needs and suggested owner as a person decides. `link` refuses a `depends-on` that would close a cycle.
|
||||
|
||||
`groom` triages every issue not resolved and not yet triaged, oldest first, against the older ones not resolved
|
||||
and not found a duplicate in the same pass. It writes only the pass, in the state `grooming` (the last pass, one
|
||||
key), each finding saying what applying it would do, and applies exactly that pass on `confirm`, each issue
|
||||
checked again. One judgement runs at a time; the pass waits while a new issue's triage waits. A triage may take up
|
||||
to two minutes, which the tool runner allows a handler while keeping its event alive (hq issue 387).
|
||||
|
||||
The new values are optional keys of an issue's one JSON value: an issue kept before reads as having none; the
|
||||
key-value state has no schema to migrate.
|
||||
|
||||
## The import of hq's issues (slice 3)
|
||||
|
||||
@@ -159,8 +173,8 @@ verb takes an argument naming a caller, and none can be given one.
|
||||
|
||||
## Settings
|
||||
|
||||
`duplicate-check` (`on`; `off` stops the check on new issues) and `judge-model` (`sonnet`; `haiku` or `opus`)
|
||||
steer the duplicate check.
|
||||
`duplicate-check` (`on`; `off` stops the triage of new issues), `judge-model` (`sonnet`; `haiku` or `opus`) and
|
||||
`forge-owner` (the forge's owner of the repositories `fixed-by` names, for asking a delivery) steer the triage.
|
||||
|
||||
```
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user