Merge pull request 'ADR 0283: an agent moves an issue to fixing under its own name, and an issue is resolved only from fixing (issue 399)' (#295) from feat/399-fixing-status into main
This commit was merged in pull request #295.
This commit is contained in:
@@ -24,14 +24,16 @@ result is not "nothing to learn" — it is the reason the next person repeats th
|
||||
## Steps
|
||||
|
||||
1. Read the issue: `mesh_call issue-tracker.get` with its number, and `00-report.md` when it has a
|
||||
folder. Move it to `diagnosing` with `issue-tracker.move`.
|
||||
folder. Before you start, move it to `diagnosing` with `issue-tracker.move` and `by`, your name and node as
|
||||
who@node (such as `fix-399@laptop`). The tracker refuses it while another worker is current, naming them.
|
||||
2. Investigate. The trail goes in `issue-tracker.note`, **dated** in its text, including what was
|
||||
ruled out and how; for an issue with a folder, in `01-diagnosis.md` there as well. Archaeology —
|
||||
which commit, which pull request, which date a behaviour changed — is the most valuable content.
|
||||
3. When the owner is known, `issue-tracker.move` to `located` with `located-in`: entries of the
|
||||
tracker's registered list of owners (repositories, and modules as `mesh-catalog modules/<module>`);
|
||||
the tracker refuses an owner it does not know.
|
||||
4. On resolution: `issue-tracker.move` to `resolved` with `fixed-by`, and `replay` or `replay-none`
|
||||
4. Before you start the fix: `issue-tracker.move` to `fixing` with `by`.
|
||||
5. On resolution: `issue-tracker.move` to `resolved`, taken only from `fixing`, with `fixed-by`, and `replay` or `replay-none`
|
||||
for a core issue. If the root cause was a design gap, run `hq-graduate` for the amendment and give
|
||||
`amended-design`. Nothing of this is written in the report's frontmatter.
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ generated on demand and never written back to disk.
|
||||
| Research | `01-RESEARCH/NNN-*/00-overview.md` | `status` (`active` / `graduated` / `abandoned`), `initiated`, `touches`, `became` |
|
||||
| Design | `03-DESIGN/**/*.md` (not READMEs) | `layer` (`as-is` / `to-be`), `status` (`designed` / `in-progress` / `implemented` / `abandoned`), `code`, `updated`, `decisions` |
|
||||
| Decisions | `02-DECISIONS/NNNN-*.md` | `status` (`proposed` / `accepted` / `superseded`), `date`, `deciders`, `reconstructed`, `superseded-by`, `extends` |
|
||||
| Issues | the issue tracker, not a file: `mesh_call issue-tracker.list` (optionally `status`, `owner`, `phrase`) and `issue-tracker.get` | `status` (`open` / `diagnosing` / `located` / `resolved` / `wontfix`), `opened`, `located-in`, `fixed-by`, `amended-design`, `record` (the folder here, when it has one) |
|
||||
| Issues | the issue tracker, not a file: `mesh_call issue-tracker.list` (optionally `status`, `owner`, `phrase`) and `issue-tracker.get` | `status` (`open` / `diagnosing` / `located` / `fixing` / `resolved` / `wontfix`), `worker` and `stale` while `diagnosing` or `fixing`, `opened`, `located-in`, `fixed-by`, `amended-design`, `record` (the folder here, when it has one) |
|
||||
|
||||
## Steps
|
||||
|
||||
|
||||
+6
-1
@@ -551,7 +551,7 @@ asking, never the act. **Decided by** ADR 0152, 0175, 0234, 0259, 0272.
|
||||
## The record — how this repository works
|
||||
|
||||
Not a domain of the mesh but of the way it is built, listed because its words meet the mesh's.
|
||||
**Recorded in** this repository and the issue tracker. **Decided by** ADR 0019, 0080, 0244, 0275.
|
||||
**Recorded in** this repository and the issue tracker. **Decided by** ADR 0019, 0080, 0244, 0275, 0283.
|
||||
|
||||
- **research effort**, **graduation**, **hand-off**, **playbook** — an investigation in `01-RESEARCH/`;
|
||||
its closing into a decision and a design; a design given to a code repository; a documented workflow
|
||||
@@ -576,6 +576,11 @@ Not a domain of the mesh but of the way it is built, listed because its words me
|
||||
duplicate (the **duplicate check**), its **severity** and what it **needs**, a suggested owner, and the issues it
|
||||
depends on or relates to; it fills only what nobody gave ([ADR 0279](../02-DECISIONS/0279-the-issue-tracker-triages-every-new-issue-and-an-issue-is-ready-when-what-it-depends-on-is-delivered.md)).
|
||||
- **ready** — of an issue: every issue it depends on is wontfix, or resolved with its fix delivered.
|
||||
- **worker** — of an issue: the agent or person, with its node (who@node), that moved it to `diagnosing` or `fixing`
|
||||
and works on it; another is refused while the worker is current, unless it gives a reason to **take it over**. A
|
||||
worker with nothing done on the issue for a day is **stale**. **Fixing** is the status an issue is at while its fix
|
||||
is worked on; an issue is resolved only from it ([ADR 0283](../02-DECISIONS/0283-an-agent-moves-an-issue-to-fixing-under-its-own-name-and-an-issue-is-resolved-only-from-fixing.md)).
|
||||
Not a *claim* or a *holder*, which are a module's on a seat.
|
||||
- **hq check** — one of `00-META/checks/`, run by `merge-check.sh` as this repository's check.
|
||||
|
||||
## Homonyms
|
||||
|
||||
@@ -71,10 +71,20 @@ import read, which every imported issue names (`imported.commit` in `issue-track
|
||||
drift.
|
||||
|
||||
**An issue wholly in the tracker** is done at this step.
|
||||
2. Investigate. The trail goes in `issue-tracker.note`, and, for a folder-backed issue, in `01-diagnosis.md` in the
|
||||
same folder as well — dated, including what was ruled out. The status moves through `issue-tracker.move`:
|
||||
to `diagnosing`, then to `located` with `located-in`, which the tracker refuses without a registered owner.
|
||||
3. Resolve. `issue-tracker.move` to `resolved` with `fixed-by`, and, if the root cause was a design gap,
|
||||
2. Investigate. **Before you start, move the issue to `diagnosing` with `by`**: who works on it and its node, as
|
||||
who@node (`fix-399@laptop`, `operator@workstation`). The tracker keeps you as the issue's **worker**, and `get` and `list`
|
||||
show it with since when. The trail goes in `issue-tracker.note`, and, for a folder-backed issue, in
|
||||
`01-diagnosis.md` in the same folder as well — dated, including what was ruled out. A note keeps you the worker; a
|
||||
worker with nothing done on the issue for a day is stale. Then move it to `located` with `located-in`, which the
|
||||
tracker refuses without a registered owner; that ends your work on it.
|
||||
3. Fix. **Before you start the fix, move the issue to `fixing` with `by`**, even when you diagnosed it yourself. The
|
||||
tracker refuses the move while another worker is current, naming them: ask them, or take it over with
|
||||
`take-over` saying why, which is noted on the issue. A stale worker may be taken over from without a reason.
|
||||
Name the fix in `fixed-by` when it merges, with a move to `fixing` that gives `by` again; the issue stays
|
||||
`fixing` until the acceptance is proven live
|
||||
([ADR 0283](../../02-DECISIONS/0283-an-agent-moves-an-issue-to-fixing-under-its-own-name-and-an-issue-is-resolved-only-from-fixing.md),
|
||||
[ADR 0281](../../02-DECISIONS/0281-an-issue-knows-whether-its-fix-is-delivered-and-a-fix-stuck-after-its-merge-is-loud.md)).
|
||||
4. Resolve. `issue-tracker.move` to `resolved`, which the tracker takes only from `fixing`, with `fixed-by`, and, if the root cause was a design gap,
|
||||
run playbook [02](02-graduation.md) and give `amended-design`. **A core issue** — its `located-in`
|
||||
names the controller, the node-engine, the tool runner, the SDK, or the catalogue's bus, forge or build
|
||||
agent — resolves with `replay`, the id of its replay in mesh-lab's replays register, proved to fail on
|
||||
@@ -97,8 +107,11 @@ import read, which every imported issue names (`imported.commit` in `issue-track
|
||||
- An issue whose answer is a general lesson should also be written to the knowledge base, so
|
||||
the next person searching a symptom finds it. Both, not either.
|
||||
- `wontfix` is legitimate and requires a sentence saying why; the tracker refuses it without one.
|
||||
- **A rule states how it is checked.** The cycle's rules on an issue — a status one of the five, `located` with an
|
||||
owner, `resolved` with a fix, a core issue with its replay, `wontfix` with a reason — are refused at the write by
|
||||
- **An agent says when it starts work on an issue**, by moving it to `diagnosing` or `fixing` with `by`. Two agents
|
||||
never start the same work without knowing: the second is refused, naming the first.
|
||||
- **A rule states how it is checked.** The cycle's rules on an issue — a status one of the six, `diagnosing` and
|
||||
`fixing` with a worker and no other current one, `located` with an owner, `resolved` only from `fixing` and with a
|
||||
fix, a core issue with its replay, `wontfix` with a reason — are refused at the write by
|
||||
`issue-tracker.move` (mesh-catalog `modules/mesh-issues`, its table test over the rules). `cycle.py` checks what
|
||||
this repository still holds: no two folders share a number, every report has frontmatter with the day it was
|
||||
`opened:`, and no report carries a status key.
|
||||
|
||||
+7
@@ -116,6 +116,13 @@ along the way".
|
||||
`resolved` need `located-in`; `resolved` needs `fixed-by`; a core issue resolves with `replay` or `replay-none`
|
||||
([ADR 0237](0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md));
|
||||
`wontfix` needs a reason. `located-in` names an entry of a registered list of repositories and modules.
|
||||
|
||||
> **The mechanism changed — 2026-10-10, by [ADR 0283](0283-an-agent-moves-an-issue-to-fixing-under-its-own-name-and-an-issue-is-resolved-only-from-fixing.md).**
|
||||
> What still stands: the cycle's rules are enforced at the write, and §5 for who acted. What moved: there are six
|
||||
> statuses, `fixing` between `located` and `resolved`; a move to `diagnosing` or `fixing` names the issue's worker
|
||||
> in `by`, which is not the actor of §5 but who works on it as they state it; and `resolved` is reached only from
|
||||
> `fixing`.
|
||||
|
||||
7. **The word is *issue*.** The module is the *issue tracker*, named `issues`; *ticketing system* is retired in the
|
||||
glossary, and the bare word *ticket* is a homonym that never means an issue.
|
||||
8. **It is built in slices, each ending at something the operator sees.** Slice 1 is the module with `open`, `get`,
|
||||
|
||||
+5
@@ -84,6 +84,11 @@ therefore name a fix in `fixed-by` when it merges, with the issue still `located
|
||||
`move` to the status an issue already has is taken when it changes what the issue holds, such as its `fixed-by`, and
|
||||
refused when it changes nothing. `move` still requires `fixed-by` to resolve.
|
||||
|
||||
> **The mechanism changed — 2026-10-10, by [ADR 0283](0283-an-agent-moves-an-issue-to-fixing-under-its-own-name-and-an-issue-is-resolved-only-from-fixing.md).**
|
||||
> What still stands: delivered is not resolved, and an issue is resolved after the proof. What moved: the fix is
|
||||
> named while the issue stays `fixing`, not `located`, because an issue is resolved only from `fixing`, and a move
|
||||
> to `fixing` names its worker in `by`.
|
||||
|
||||
### 4. A stuck fix is loud
|
||||
|
||||
A fix merged and not delivered after **two hours** (the module's setting `stuck-after`) is said once: a note on the
|
||||
|
||||
+169
@@ -0,0 +1,169 @@
|
||||
---
|
||||
topic: how we work
|
||||
status: accepted
|
||||
date: 2026-10-10
|
||||
deciders: jochen
|
||||
reconstructed: false
|
||||
extends: 02-DECISIONS/0275-the-mesh-numbers-and-tracks-its-issues-in-a-module-of-its-own-and-hq-keeps-only-the-narrative-of-a-design-or-governance-issue.md
|
||||
---
|
||||
|
||||
# 283. An agent moves an issue to fixing under its own name, and an issue is resolved only from fixing
|
||||
|
||||
## Context
|
||||
|
||||
On 2026-10-10 the operator asked that an agent say when it starts work on an issue, and chose the word for the
|
||||
status it moves the issue to: **fixing**. The statuses become open → diagnosing → located → fixing → resolved, or
|
||||
wontfix.
|
||||
|
||||
**What the tracker holds, measured on 2026-10-10** (`issue-tracker.list`): 43 issues at `open`, 1 at `diagnosing`,
|
||||
51 at `located`. Nothing on an issue says who works on it. Two agents can start on the same issue and neither sees
|
||||
the other. Every move is recorded as by `unproven`: the runtime does not hand a module the identity of its caller
|
||||
(issue 340), so [ADR 0275](0275-the-mesh-numbers-and-tracks-its-issues-in-a-module-of-its-own-and-hq-keeps-only-the-narrative-of-a-design-or-governance-issue.md)
|
||||
§5 ("the caller is the bus credential, never an argument") records nobody in particular. And an issue moves to
|
||||
`resolved` from any status, so nothing shows that anyone said they started the fix before it was resolved.
|
||||
|
||||
[To-be 53](../03-DESIGN/01-to-be/53-the-issue-tracker.md) names "claims" under *What it leaves out*, as needing a
|
||||
decision of its own. This is that decision. The glossary already uses *claim* for a module taking a spot on a seat,
|
||||
and *holder* for the module that holds a seat, so neither names the person or agent working on an issue. The
|
||||
glossary has no word for that; this record proposes **worker**, added to the glossary in the same change.
|
||||
|
||||
The record was searched first ("claim", "who works on", "assignee", "fixing", "take over"): to-be 53's *What it
|
||||
leaves out*, ADR 0275 §5 and §6, and [ADR 0281](0281-an-issue-knows-whether-its-fix-is-delivered-and-a-fix-stuck-after-its-merge-is-loud.md)
|
||||
§3, which has an agent name a fix while the issue stays `located`.
|
||||
|
||||
## Considered Options
|
||||
|
||||
### How the worker is named
|
||||
|
||||
1. *The caller's identity, as the runtime proves it.* Not possible as the mesh stands: the runtime does not say who
|
||||
called (issue 340). When it does, a node's credential is shared by every session on that node, so two agents on
|
||||
one machine would still read as one.
|
||||
2. **`by`, given by the worker on the move, as who@node.** Chosen. The worker states its own name. ADR 0275 §5
|
||||
still holds for *who acted*: the tracker keeps recording that from the runtime, never from an argument. `by` names
|
||||
who works on the issue, which is a different fact. Because a worker names itself, the refusal below lets honest
|
||||
workers see each other; it does not stop a worker that gives a false name.
|
||||
3. *An assignee, set by the operator or the triage.* Refused. Nobody hands out work: agents choose it from `list`,
|
||||
and the triage estimates and does not decide.
|
||||
|
||||
### What a second worker meets
|
||||
|
||||
1. *Nothing: both are shown.* Refused. Two agents starting the same fix without knowing is what this record prevents.
|
||||
2. **A refusal naming the worker, unless the move says why it takes the issue over; the reason is noted.** Chosen.
|
||||
3. *A refusal with no way past it until the worker moves on.* Refused. An agent whose session ended would keep the
|
||||
issue forever.
|
||||
|
||||
### When a worker counts as gone
|
||||
|
||||
1. *A fixed time after the worker started.* Refused. A long fix that keeps writing notes would lose its issue.
|
||||
2. **A time with nothing done on the issue: no move, note, link or set by a caller.** Chosen. The tracker's own
|
||||
writes (the triage, the duplicate check, the delivery's notes) do not count, because they say nothing about
|
||||
whether the worker is still there.
|
||||
|
||||
### What may be resolved
|
||||
|
||||
1. *Any issue with a fix named, as today.* Refused. Nothing shows that anyone started the fix.
|
||||
2. **Only an issue at `fixing`.** Chosen. This is the check that the agent rule holds: to resolve an issue, someone
|
||||
must first have moved it to `fixing` under their own name.
|
||||
|
||||
## Decision
|
||||
|
||||
### 1. Six statuses
|
||||
|
||||
An issue is `open`, `diagnosing`, `located`, `fixing`, `resolved` or `wontfix`. **Fixing** means someone works on its
|
||||
fix. `wontfix` is unchanged: it is reached from any status, with a reason.
|
||||
|
||||
### 2. A move to diagnosing or fixing names its worker
|
||||
|
||||
A move to `diagnosing` or `fixing` needs `by`: the issue's **worker**, the agent or person who works on it and the
|
||||
node it works on, written as who@node (`fix-399@laptop`, `operator@workstation`). These are the limits:
|
||||
|
||||
- `who` is letters, digits and `.`, `_`, `/`, `-`;
|
||||
- `node` is lower-case letters, digits and `-`;
|
||||
- the whole is at most 120 bytes and is kept in lower case;
|
||||
- it is refused when it has the shape of a secret, like any field of an issue.
|
||||
|
||||
The issue keeps its worker (`by`, `since`, and `active`, the last time a caller did anything on it) while it stays
|
||||
at `diagnosing` or `fixing`. A move to any other status ends the work. The same worker moving the issue from
|
||||
`diagnosing` to `fixing` keeps its `since`. A move to `fixing` that names a fix while the issue stays `fixing` is a
|
||||
move to `fixing` too, and needs `by`. `by` on a move to any other status is refused. `get` shows the worker, and
|
||||
each row of `list` shows `worker`, `since` and `stale`.
|
||||
|
||||
### 3. Another worker is refused while the worker is current
|
||||
|
||||
A move to `diagnosing` or `fixing` by a different worker is refused while the worker is current. The refusal names
|
||||
the worker, since when it has worked on the issue, and when it was last active. A move that gives `take-over` with a
|
||||
reason takes the issue over, and a note on the issue says who took it from whom and why. `take-over` is refused
|
||||
when nobody else works on the issue, and on a move to a status that has no worker.
|
||||
|
||||
### 4. A worker who did nothing for a day is stale
|
||||
|
||||
A worker with no move, note, link or set by a caller on the issue for `worker-stale-after` (a setting of the module,
|
||||
**24 hours** by default) is **stale**. `list` says `stale`, `get` says `worker-stale`, and another worker may take the
|
||||
issue over without a reason; the take-over is still noted. 24 hours is a working day and a night. An agent whose
|
||||
session ended, or whose machine is asleep, frees the issue by the next day. An agent that is still working keeps it
|
||||
by noting what it found, which playbook 03 already asks for.
|
||||
|
||||
### 5. Resolved is reached only from fixing
|
||||
|
||||
A move to `resolved` is refused unless the issue is at `fixing`. An issue already resolved may still have what it
|
||||
holds corrected. The other rules for `resolved` (`located-in`, `fixed-by`, and a replay for a core issue) are
|
||||
unchanged.
|
||||
|
||||
### 6. The event and the reads carry the worker
|
||||
|
||||
The `moved` event carries:
|
||||
|
||||
- `by`: the worker, when the move names one; who acted, for a move that names none;
|
||||
- `since`: when the worker started;
|
||||
- `caller`: who acted, as the runtime proves it (`unproven` today);
|
||||
- `took-over-from` and `take-over`: on a take-over;
|
||||
- `released`: the worker whose work the move ended.
|
||||
|
||||
`get` carries `worker` and `worker-stale`. Another module can read who works on an issue from either. No event
|
||||
carries a secret, because `by` and the take-over reason are refused when they have the shape of one.
|
||||
|
||||
### 7. Fixing is not closed
|
||||
|
||||
The duplicate check, the triage, readiness and the ready-to-verify note treat `fixing` like `diagnosing` and
|
||||
`located`. A fix is named in `fixed-by` while the issue stays at `fixing`, and the issue is resolved after the proof
|
||||
(ADR 0281 §3, which said `located`).
|
||||
|
||||
### 8. Agents say when they start
|
||||
|
||||
An agent moves an issue to `diagnosing` or `fixing` with `by` before it starts work on it. Playbook 03 says so. The
|
||||
rule for every session is proposed through the agent module's shared instructions and taken on the operator's
|
||||
warrant ([ADR 0274](0274-an-agent-proposes-a-shared-instruction-section-and-every-node-takes-it-only-on-the-operators-warrant-which-it-proves-itself.md)).
|
||||
|
||||
## Consequences
|
||||
|
||||
- `list` shows who works on what and since when. A second agent learns of the first before it starts, not after
|
||||
both have opened pull requests.
|
||||
- Each of the 51 issues at `located` now goes through `fixing` before it is resolved. An agent that resolves one
|
||||
names itself first.
|
||||
- `by` is what the worker says it is. A false name passes, and the tracker cannot tell. The proven caller is
|
||||
tracked by issue 340.
|
||||
- A worker that stops without moving the issue on keeps others out for up to 24 hours, unless they give a reason.
|
||||
The reason is on the issue for the operator to read.
|
||||
- The next step is that an alert names the issue tracking its condition and that issue's state in plain words, such
|
||||
as "an agent on the laptop is fixing it since 21:10". That needs a link from an issue to a condition key or kind, and is
|
||||
tracked by issue 400. This record makes the worker readable for it, from `get` and from the `moved` event.
|
||||
|
||||
## How it is checked
|
||||
|
||||
| Rule | Checked by |
|
||||
|---|---|
|
||||
| A move to diagnosing or fixing names its worker as who@node; `by` or `take-over` on another status is refused; a `by` with a secret's shape is refused | the tracker's table test over the cycle's rules (mesh-catalog `modules/mesh-issues`), one row per refusal, each refused row changing nothing and saying no event |
|
||||
| Another worker is refused while the worker is current, naming the worker | the tracker's test of a second worker at `diagnosing` and at `fixing`, 23 hours after the first: refused, the issue unchanged, no event |
|
||||
| A take-over gives a reason, which is noted; the event says from whom | the tracker's take-over test: the note, the worker, and `took-over-from` and `take-over` on the `moved` event |
|
||||
| A stale worker is shown and may be taken over from without a reason; a caller's note keeps the worker current, the tracker's own note does not; the bound is the setting | the tracker's stale-worker tests, with a clock the test moves |
|
||||
| **Resolved only from fixing.** This is the check that the agent rule holds: no issue is resolved unless someone first moved it to `fixing` under their own name | the table test's rows resolving from `open`, `located` and `diagnosing`, each refused; live, a resolve of an issue at `located` is refused |
|
||||
| Fixing is not closed | the tracker's test that every status but `resolved` and `wontfix` is offered to the triage |
|
||||
| Live | an agent moves its issue to `fixing` with `by`, and `get` and `list` show the worker with since; a resolve of an issue at `located` is refused, naming the rule |
|
||||
|
||||
## References
|
||||
|
||||
- [ADR 0275](0275-the-mesh-numbers-and-tracks-its-issues-in-a-module-of-its-own-and-hq-keeps-only-the-narrative-of-a-design-or-governance-issue.md): the tracker and its rules, which this record extends
|
||||
- [ADR 0281](0281-an-issue-knows-whether-its-fix-is-delivered-and-a-fix-stuck-after-its-merge-is-loud.md): delivered is not resolved; the fix is now named while the issue is `fixing`
|
||||
- [ADR 0274](0274-an-agent-proposes-a-shared-instruction-section-and-every-node-takes-it-only-on-the-operators-warrant-which-it-proves-itself.md): how the rule for every session is taken
|
||||
- [To-be 53](../03-DESIGN/01-to-be/53-the-issue-tracker.md): the design this record amends
|
||||
- Playbook [03 — issues](../00-META/process/03-issues.md)
|
||||
@@ -8,6 +8,7 @@ decisions:
|
||||
- 02-DECISIONS/0278-the-issue-tracker-checks-every-new-issue-for-a-duplicate-through-a-judgement-the-agent-makes-without-tools.md
|
||||
- 02-DECISIONS/0279-the-issue-tracker-triages-every-new-issue-and-an-issue-is-ready-when-what-it-depends-on-is-delivered.md
|
||||
- 02-DECISIONS/0281-an-issue-knows-whether-its-fix-is-delivered-and-a-fix-stuck-after-its-merge-is-loud.md
|
||||
- 02-DECISIONS/0283-an-agent-moves-an-issue-to-fixing-under-its-own-name-and-an-issue-is-resolved-only-from-fixing.md
|
||||
---
|
||||
|
||||
# 53 — The issue tracker
|
||||
@@ -68,8 +69,8 @@ agent finds them with `mesh_search` ("open an issue") and calls them as `issue-t
|
||||
|---|---|---|
|
||||
| `open` | a title, the report as text, optionally `located-in` and a folder path | checks the issue, then takes the next number and writes it; returns the number. Refuses an empty title or report, and an owner not on the registered list |
|
||||
| `get` | a number | the issue whole: fields, notes, links |
|
||||
| `list` | optionally a status, an owner, a phrase | compact rows, newest first, short enough to read in a chat: number, status, owner, title |
|
||||
| `move` | a number, a status, and what that status needs | changes the status under the rules of § 5 |
|
||||
| `list` | optionally a status, an owner, a phrase | compact rows, newest first, short enough to read in a chat: number, status, owner, title, and the worker with since and whether it is stale |
|
||||
| `move` | a number, a status, and what that status needs; `by` for `diagnosing` and `fixing`, and `take-over` with a reason to take an issue over from another worker | changes the status under the rules of § 5 |
|
||||
| `note` | a number and a text | appends to the issue's notes; a note is never edited |
|
||||
| `link` | a number, a kind and a target, or `remove` | adds or removes a typed link |
|
||||
| `set` | a number and any of `severity`, `needs`, `suggested-owner` | changes them as a person decides (§ 10) |
|
||||
@@ -80,11 +81,16 @@ Each verb's description says in plain words what it does and what it refuses, wi
|
||||
an agent picks the right one from `mesh_search` alone. A refusal says what was wrong and what would be accepted.
|
||||
|
||||
**The caller is the bus credential, never an argument.** The runtime hands the module the identity of each call's
|
||||
caller; the module records that identity as who acted. No verb takes an actor.
|
||||
caller; the module records that identity as who acted. No verb takes an actor. `by` on `move` is not one: it names
|
||||
the issue's worker, who works on it, as the worker states it
|
||||
([ADR 0283](../../02-DECISIONS/0283-an-agent-moves-an-issue-to-fixing-under-its-own-name-and-an-issue-is-resolved-only-from-fixing.md)).
|
||||
|
||||
## 3. What one issue holds
|
||||
|
||||
- `number` (its key), `title`, `status` (`open`, `diagnosing`, `located`, `resolved`, `wontfix`), `opened`, `closed`;
|
||||
- `number` (its key), `title`, `status` (`open`, `diagnosing`, `located`, `fixing`, `resolved`, `wontfix`), `opened`,
|
||||
`closed`;
|
||||
- `worker`, while it is `diagnosing` or `fixing`: who works on it as who@node, `since` when, and `active`, the last
|
||||
time a caller did anything on it (§ 5);
|
||||
- `located-in`: entries of the registered list of owners (repositories and modules), never free text;
|
||||
- `fixed-by` (pull requests or commits), `amended-design`, `replay` or `replay-none`, and a reason for `wontfix`;
|
||||
- `notes`: appended, each with who wrote it, when, and the text;
|
||||
@@ -137,7 +143,9 @@ at the moment the module is switched on. Numbers already skipped stay unused, an
|
||||
**Every change is an event the module declares** under `emits`
|
||||
([ADR 0041](../../02-DECISIONS/0041-events-are-a-relationship.md)): `opened`, `moved`, `noted`, `linked`. Each carries
|
||||
the number, what changed, and who changed it, so the events are the audit trail, and anything watching the bucket or
|
||||
the events sees a change as it happens. No event carries a secret, and an issue holds none.
|
||||
the events sees a change as it happens. `moved` also carries the worker a move names, as `by`, with `since`, and who
|
||||
acted as `caller`; on a take-over `took-over-from` and the reason, and `released` when a move ends the work. No
|
||||
event carries a secret, and an issue holds none.
|
||||
|
||||
## 5. The cycle's rules, at the write
|
||||
|
||||
@@ -145,13 +153,17 @@ the events sees a change as it happens. No event carries a secret, and an issue
|
||||
|
||||
| The issue moves to | Needs |
|
||||
|---|---|
|
||||
| any status | one of the five |
|
||||
| any status | one of the six |
|
||||
| `diagnosing` or `fixing` | `by`, the worker as who@node; refused while another worker is current, naming them, unless `take-over` gives a reason, which is noted; a worker with nothing done on the issue for `worker-stale-after` (24 hours) is stale and may be taken over from without one |
|
||||
| any other status | no `by` and no `take-over`; the move ends the work |
|
||||
| `located` | `located-in` names at least one registered owner |
|
||||
| `resolved` | `located-in`, and `fixed-by` saying what fixed it |
|
||||
| `resolved` | the issue is at `fixing` (or already `resolved`, to correct what it holds); `located-in`, and `fixed-by` saying what fixed it |
|
||||
| `resolved`, for a core issue (its `located-in` names the controller, the node-engine, the tool runner, the SDK, or the catalogue's bus, forge or build agent) | `replay` (an id from mesh-lab's replays register) or `replay-none` saying why none is possible ([ADR 0237](../../02-DECISIONS/0237-a-change-is-judged-against-the-mesh-that-runs-before-it-merges-on-the-build-seat.md)) |
|
||||
| `wontfix` | a reason |
|
||||
|
||||
A refused move changes nothing and says which rule refused it. `cycle.py` checked the folders that carried status until
|
||||
A refused move changes nothing and says which rule refused it. The rows for `diagnosing`, `fixing` and `resolved` are
|
||||
[ADR 0283](../../02-DECISIONS/0283-an-agent-moves-an-issue-to-fixing-under-its-own-name-and-an-issue-is-resolved-only-from-fixing.md)'s:
|
||||
resolved only from `fixing` is the check that an agent said it started the fix. `cycle.py` checked the folders that carried status until
|
||||
slice 3; since then it refuses a status key in any report, and judges no issue's status.
|
||||
|
||||
## 6. How the operator and agents use it
|
||||
@@ -161,6 +173,11 @@ or governance issue, writes `04-ISSUES/NNN-slug/` under it with the number in th
|
||||
changes to that the day slice 1 is live; nothing else in playbook 03 changes in slice 1. `list` answers "what is open"
|
||||
in one call, from any session, and the responder on a channel answers from it once the seat exists.
|
||||
|
||||
**An agent says when it starts.** Before it starts work on an issue, an agent moves it to `diagnosing` (to find where
|
||||
it lives) or `fixing` (to fix it) with `by`, its own name and node. `list` then shows who works on what, and a second
|
||||
agent is refused before it starts the same work. An agent that keeps working notes what it finds, which keeps it the
|
||||
worker; one that stops moves the issue on, or is stale a day later.
|
||||
|
||||
## 7. How it is checked
|
||||
|
||||
| Rule | Checked by |
|
||||
@@ -171,6 +188,7 @@ in one call, from any session, and the responder on a channel answers from it on
|
||||
| The cycle's rules hold at the write | the module's table test over § 5, one case per row, each refused case changing nothing |
|
||||
| The module creates no bucket | the runtime refuses a module that tries (ADR 0201 §3); the controller's raise asserts both buckets |
|
||||
| The caller is who acted | the module's test that the recorded actor is the call's identity, whatever the arguments say |
|
||||
| A worker is named on a move to diagnosing or fixing, another is refused while it is current, a take-over is noted, a stale one may be taken over from, and resolved is reached only from fixing | the rows of [ADR 0283](../../02-DECISIONS/0283-an-agent-moves-an-issue-to-fixing-under-its-own-name-and-an-issue-is-resolved-only-from-fixing.md)'s "How it is checked" |
|
||||
| An issue's delivery line follows the delivery; ready to verify once; a stuck fix said once and cleared | the rows of [ADR 0281](../../02-DECISIONS/0281-an-issue-knows-whether-its-fix-is-delivered-and-a-fix-stuck-after-its-merge-is-loud.md)'s "How it is checked" |
|
||||
| The triage fills only what is empty, links no cycle, and an issue is ready only when its dependencies' fixes are delivered | the rows of [ADR 0279](../../02-DECISIONS/0279-the-issue-tracker-triages-every-new-issue-and-an-issue-is-ready-when-what-it-depends-on-is-delivered.md)'s "How it is checked" |
|
||||
| The duplicate check acts only on a clear duplicate, never on an older or a resolved issue, once per issue, loudly when it cannot judge | the rows of [ADR 0278](../../02-DECISIONS/0278-the-issue-tracker-checks-every-new-issue-for-a-duplicate-through-a-judgement-the-agent-makes-without-tools.md)'s "How it is checked" |
|
||||
@@ -195,7 +213,7 @@ within a few minutes, keeping its report on the older one; an issue that repeats
|
||||
was checked** ([ADR 0278](../../02-DECISIONS/0278-the-issue-tracker-checks-every-new-issue-for-a-duplicate-through-a-judgement-the-agent-makes-without-tools.md)).
|
||||
|
||||
- **Started by the tracker's own `opened` event**, which the module consumes. Only an issue still at `open` is
|
||||
checked, against every older issue at `open`, `diagnosing` or `located`; resolved and wontfix issues are never
|
||||
checked, against every older issue at `open`, `diagnosing`, `located` or `fixing`; resolved and wontfix issues are never
|
||||
offered or changed.
|
||||
- **Judged in two questions** to the agent module's `claude_code_judge` on the tracker's node: a shortlist of at
|
||||
most five by titles, then a verdict on the reports (`duplicate`, `related` or `none`, whether it is certain,
|
||||
@@ -249,13 +267,14 @@ stuck after its merge is said** ([ADR 0281](../../02-DECISIONS/0281-an-issue-kno
|
||||
- `get` and each row of `list` carry **delivery**, one line: "fix not delivered: …", "held: …", "fix merged, not
|
||||
delivered", "fix not merged", "nothing heard …", "delivered to every machine it should reach".
|
||||
- When every fix of an issue not yet resolved is delivered, it gains a note and the event `ready-to-verify`, once;
|
||||
it is resolved after the acceptance is proven live. A fix is named while the issue stays `located`: `move` to the
|
||||
same status changes what the issue holds.
|
||||
it is resolved after the acceptance is proven live. A fix is named while the issue stays `fixing`: `move` to the
|
||||
same status, with `by`, changes what the issue holds.
|
||||
- A fix merged and not delivered after `stuck-after` (two hours) is said once: a note on the issue and a warning on
|
||||
the operator's channel, cleared when it is delivered. It is not a controller condition: a module that runs only
|
||||
its bundle cannot raise one.
|
||||
|
||||
## What it leaves out
|
||||
|
||||
Priorities beyond severity, claims, notifications beyond the `ready` and `ready-to-verify` events and the stuck-fix warning, full-text or semantic search, the forge's own issue lists, and an index of any kind:
|
||||
none of them is in any slice above, and each needs a decision of its own.
|
||||
Priorities beyond severity, notifications beyond the `ready` and `ready-to-verify` events and the stuck-fix warning, full-text or semantic search, the forge's own issue lists, and an index of any kind:
|
||||
none of them is in any slice above, and each needs a decision of its own. Who works on an issue, listed here until
|
||||
2026-10-10, is settled by [ADR 0283](../../02-DECISIONS/0283-an-agent-moves-an-issue-to-fixing-under-its-own-name-and-an-issue-is-resolved-only-from-fixing.md).
|
||||
|
||||
Reference in New Issue
Block a user