feat: promote clusters to breadboard issues and track them #6

Merged
Breadway merged 3 commits from feature/promote into main 2026-10-12 09:52:09 +08:00
Owner

Closes BUG-8

Stacked on #5. Part of ECO-EP1.

What

  • Promote button in the triage UI (only shown when breadboard is configured and the cluster has no issue). Creates the issue via the breadboard API: project from the app (defaults for all bread apps, overridable with BREADBUG_BOARD_PROJECTS), priority from the severity score, labels breadbug + kind, and a body that follows the standing rule for filed bugs: how it was found, confidence level, and an explanation, plus counts, affected versions, OS builds, and up to three evidence blocks (message, top symbolicated frames, user note). Evidence is untrusted report text, so it goes in code fences longer than any backtick run it contains and cannot close them.
  • Promotion is claimed atomically (pending marker) so a double click or two admins cannot create two issues; a failed create releases the claim so it can be retried.
  • After promotion: each doubling of the report count (from 4) comments on the issue and raises the priority if the score now warrants it (never lowers it). Hourly maintenance marks a cluster fixed when its issue reaches done. A report from a version not older than the recorded fix version, or (with no fix version) a version newer than anything seen before, marks the cluster regressed, comments, and reopens the issue.
  • Follow-ups run on their own thread; breadboard being down or slow never delays or fails an intake.
  • Safety: the token comes from env or a file, is sent only as a bearer header over https (or loopback), redirects are off, errors never echo the request or token, issue keys are validated before being used in paths.

Tests

  • Unit: version ordering (dev/rc/release), priority thresholds, doubling rule, evidence formatting, fence logic, project mapping, URL/key validation.
  • 8 integration tests against a mock breadboard: issue contents and auth header, fence cannot be closed by hostile notes, double promote refused / failed create retried / no board, growth comments at 4 and 8 only with monotonic priority, done marks fixed, regression vs fix version reopens the issue, regression fallback (new version newer than all seen), admin button CSRF and visibility, the board token never appears in stored data.
  • clippy -D warnings clean. Full suite: 112 passing.

Notes

  • Needs a dedicated minimum-scope breadboard API token created by hand; none is created or stored by this PR.
  • Not exercised against the real breadboard in this PR (only the mock), since that would file real issues.
Closes BUG-8 Stacked on #5. Part of ECO-EP1. ## What - **Promote** button in the triage UI (only shown when breadboard is configured and the cluster has no issue). Creates the issue via the breadboard API: project from the app (defaults for all bread apps, overridable with `BREADBUG_BOARD_PROJECTS`), priority from the severity score, labels `breadbug` + kind, and a body that follows the standing rule for filed bugs: **how it was found, confidence level, and an explanation**, plus counts, affected versions, OS builds, and up to three evidence blocks (message, top symbolicated frames, user note). Evidence is untrusted report text, so it goes in code fences longer than any backtick run it contains and cannot close them. - Promotion is claimed atomically (`pending` marker) so a double click or two admins cannot create two issues; a failed create releases the claim so it can be retried. - **After promotion**: each doubling of the report count (from 4) comments on the issue and raises the priority if the score now warrants it (never lowers it). Hourly maintenance marks a cluster `fixed` when its issue reaches `done`. A report from a version not older than the recorded fix version, or (with no fix version) a version newer than anything seen before, marks the cluster `regressed`, comments, and reopens the issue. - Follow-ups run on their own thread; breadboard being down or slow never delays or fails an intake. - Safety: the token comes from env or a file, is sent only as a bearer header over https (or loopback), redirects are off, errors never echo the request or token, issue keys are validated before being used in paths. ## Tests - Unit: version ordering (dev/rc/release), priority thresholds, doubling rule, evidence formatting, fence logic, project mapping, URL/key validation. - 8 integration tests against a mock breadboard: issue contents and auth header, fence cannot be closed by hostile notes, double promote refused / failed create retried / no board, growth comments at 4 and 8 only with monotonic priority, `done` marks fixed, regression vs fix version reopens the issue, regression fallback (new version newer than all seen), admin button CSRF and visibility, the board token never appears in stored data. - clippy `-D warnings` clean. Full suite: 112 passing. ## Notes - Needs a dedicated minimum-scope breadboard API token created by hand; none is created or stored by this PR. - Not exercised against the real breadboard in this PR (only the mock), since that would file real issues.
feat: promote clusters to breadboard issues and track them
All checks were successful
check / check (push) Successful in 41s
2e9b0e6f89
A Promote action in the triage UI files a breadboard issue for a cluster:
project from the app, priority from the severity score, a body with how it
was found, a confidence level, counts, versions and fenced inert evidence.
Promotion is claimed atomically so a double click or retry cannot file two
issues. Afterwards each doubling of the report count comments on the issue
and may raise (never lower) its priority; an issue reaching done marks the
cluster fixed; a report from a version not older than the fix (or newer than
anything seen when no fix version is recorded) marks it regressed, comments
and reopens the issue. Breadboard errors never affect intake.

Refs BUG-8
fix: persist board fix version, escape issue text, retryable reopen
All checks were successful
check / check (push) Successful in 1m2s
8606bd5d08
Address review on the promotion slice:
- board.issue_state reads the workflow status plus an optional fix_version
  from the issue reply, and sync_issue_states persists it (mark_fixed) so
  the public fixed-in value and the regression threshold use the board's
  version instead of an unknown-version fixed
- the issue body flattens every user-supplied version and OS-build string
  to a single line (no injected markdown headings) and links back to the
  cluster through a configured BREADBUG_CLUSTER_URL base
- regression reopen now runs the board comment and reopen before moving
  the local state, so a board outage leaves the cluster fixed and the next
  matching report retries the reopen
- tests: done-with-fix-version persistence and regression gating, reopen
  retry across an outage, hostile version and OS-build flattening
fix: read the board fix version from a fixed-in label, document the cluster URL
All checks were successful
check / check (push) Successful in 52s
c6c7d78ff6
Address review on the promotion slice: breadboard has no fix_version field
on an issue, so the shipped version is read from a fixed-in:<version> label
(keeping the fix_version field as a forward-compatible fallback), the
BREADBUG_CLUSTER_URL knob is added to the README env list and the compose
file, and the README documents the label convention and the cluster link.
The mock board now returns the label.
Breadway force-pushed feature/promote from c6c7d78ff6
All checks were successful
check / check (push) Successful in 52s
to 87b6a8571f
All checks were successful
check / check (push) Successful in 1m5s
2026-10-12 09:21:57 +08:00
Compare
Breadway changed target branch from feature/triage to main 2026-10-12 09:52:08 +08:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Breadway/breadbug-server!6
No description provided.