Bug triage — one global queue, one dedicated agent, one permanent thread per defect

Maintainer, 2026-09-14: bug triaging should be in Essentials — re-use globally — only one bug triage queue with dedicated agent. So: this concept ships with Essentials (pre-installed for everyone), there is exactly one queue — on the control instance, fed by the pooled inbox every portal and repository already posts to (Hosting/Triage) — and exactly one agent, Essentials/Agent/bug-triage, works it. No module, portal or repository runs a triage of its own; a module that finds a bug hands it to the queue (/feedback for a person, a signed ci-failure / incident event for a machine, /bug-fix-thread for an agent already on it).

The general model is Governance/Design; the catalogue is Governance/Catalogue. This page is the Essentials package's part for defects: a red main, a production incident, a technical feedback — anything that ends in a GitHub issue today (Hosting/Triage, the mechanism) and then, too often, in silence.

The one idea

A bug gets one thread, and the thread outlives every session. It is anchored on the node that raised the defect — the Hosting/TriageItem (a ci-failure, a feedback) or the Hosting/Issue (a FleetWatch incident) — and it is closed by exactly one thing: a bug.verify activity that read the fixed behaviour on the target production instance. Not a merged PR, not a green build, not a comment saying "should be fixed". The maintainer's rule (2026-09-09): "Done", "fixed", "shipped" means production behaviour was verified.

The thread is where the bug-triage agent works, where every proposal it raises is linked, and where a person reads the whole story cold — six months later, in one place.

The chain of standards under a bug

red main · incident · feedback ──▶ Hosting/TriageItem / Hosting/Issue ──▶ ONE thread: Hosting/Triage/_Thread/{t}
                                                                             │
  bug.thread     (unattended)  open the thread, file / link the GitHub issue, name the owner repo
  bug.diagnose   (unattended)  the fixer's finding as a record: symptom · cause · evidence · fix direction
  dev.merge      (governed)    the fix PR — Role.Reviewer reviews the diff, a HUMAN maintainer signs the merge
  hosting.roll   (governed)    the deploy — Scope.Production: passkey-backed human signature   ─┐ one of the two,
  module.publish (unattended)  a node module: main IS the approved state; the lane publishes    ─┘ by what the fix touched
  bug.verify     (unattended)  the read-only proof on the target instance — closes the issue and the thread
Step Standard Proposer → Reviewer → Signers → Executor (identity) Ends with
Open bug.thread the inbox (a signed event) / a person → none → none → Propose + CreateIssue (App) the thread, the issue, the owning repository named on the item
Diagnose bug.diagnose Essentials/Agent/bug-triage → none → none → Record (Control) diagnosis on the item: symptom, root cause, evidence (log lines, node paths, run ids), the fix direction, the module page the finding goes to
Fix dev.merge the fixer (its PR) → Role.Reviewer (the diff against the diagnosis; Copilot's review is input) → a human in the repo's Role.Maintainer, never the author → MergePullRequest (App) the merge sha, linked on the item
Deploy hosting.roll — or module.publish for a node module the build server (trunk green) → Role.ReviewerRole.ProductionApprover, passkey → Build(deploy) / Workflow (App) — or nothing for a module: the lane publishes and the portals adopt the tag the target instance runs, or the module version it adopted
Verify bug.verify the fixer → none → none → Probe (Control: a read — a render, a Sample, a log query with the fingerprint absent) verified: true with the evidence, the issue closed by the activity, the thread closed
Reopen bug.thread again the inbox (the fingerprint recurs — LogIncidentFiler's reopen) the same thread, a new round

Three rules:

  1. Nothing but bug.verify closes. A merged PR moves the item to fixed, unverified; the thread stays open. A fixer that cannot verify (no access to the instance, the behaviour is not observable) says so on the item and hands the verification to a person — it does not close.
  2. The diagnosis is conserved where the module lives. bug.diagnose names the page the finding goes to ({Module}/…md, a WhatsNew entry for a user-visible fix); the fix PR carries it. A finding that lives only in the thread is lost to the next session.
  3. The fixer never merges, never deploys, never holds a token. It writes code, opens the PR, proposes dev.merge, follows, proposes bug.verify. The merge is a human's signature; the deploy is the production scope's.

What the thread carries

Who does what

Role Human / agent Does Never
Role.BugTriage Essentials/Agent/bug-triage — the ONE agent on the ONE queue classifies the red, files the issue, opens the thread, diagnoses, writes the fix, opens the PR, proposes merge / verify, conserves the finding merges, deploys, closes without verification
Role.Reviewer the reviewer agent + a person for production accepts / declines dev.merge on the diff vs the diagnosis signs
Role.Maintainer a human signs dev.merge reviews their own PR
Role.ProductionApprover a human, passkey signs the deploy
Reconnecting…
The server was updated. Reloading the page to pick up the latest version.