Signal
Triage the bugs and suggestions customers report, and tell them when the work ships.
A signal is one bug or one suggestion. Each person who reported it is a reporter on that signal. Everyone in the organization can file, triage, edit and delete signals. Connecting Linear or GitHub needs an admin or owner, see Issue trackers.
Where signals come from
| Source | How it files |
|---|---|
| The agent | Files from a conversation when Track bugs and suggestions is on under Agent → Behavior. The switch is on by default. At most 3 signals per conversation. |
| The feedback panel | AI reads each note and files it as a bug or a suggestion, or drops it as spam. Needs the same switch. |
| Crash reports | reportError files a bug at High priority. Needs the same switch. |
| Notes from elsewhere | median feedback submit, POST /v1/feedback, or median.feedback.submit over MCP. Read the same way as a feedback panel note. |
| Filed directly | New signal on this page, median signals file, POST /v1/signals, median.signals.file over MCP, or the assistant. |
With Track bugs and suggestions off, the agent, the feedback panel, crash reports and notes from elsewhere file nothing. Filing directly still works.
Duplicate checks and feedback reading run on AI and use credits, see Plans.
Duplicates
| Check | Rule |
|---|---|
| Same title | A new report whose title matches a signal of the same kind joins it. Matching ignores case and punctuation, and includes the titles of merged duplicates. It looks at the 60 most recently updated signals of the same kind that are not Declined. |
| AI read | A new signal from the agent, a note or a crash report is compared with the 40 most recently updated signals of the same kind that are not Declined. A match merges it into the older one. It is skipped once a teammate has changed the new signal. |
| Same person | One report per person per signal. A repeat updates their quote and adds the new conversation to the report. |
A report about a Declined signal starts a new signal. A report about a Done signal joins it, and the agent tells the customer it was fixed and asks them to try again.
The list
Signal → All shows the 60 most recently updated signals, bugs and suggestions together. A red Bug or blue Suggestion tag marks each one. The Signal item in the sidebar counts the signals waiting in Approvals.
| Part | What it holds |
|---|---|
| Approvals | Open signals, each as a card with Accept, Decline and Go to thread |
| In review, In progress, Planned | Expanded when the page loads |
| Done, Declined | Collapsed when the page loads. Click the heading to expand. |
With nothing filed, the page reads "No bugs or suggestions reported yet."
A row
| Part | Does |
|---|---|
| Priority glyph | Opens a menu to change the priority |
| Status glyph | Opens a menu to change the status |
| Title | Opens the signal's page |
| Commit glyph and count | Commits that may have fixed it, waiting for a decision |
Linear identifier or GitHub #12 | Opens the issue |
| People glyph and count | How many people reported it |
| Time | Since the last change |
| Chat glyph | Go to thread, the newest conversation it was reported from |
| More actions menu | The row menu below |
| Row menu item | Shown when |
|---|---|
| Edit | Always. Changes the title and details. |
| Go to thread | It was reported from a conversation |
| Mark done | It is not Done |
| Decline | It is past Open and not Declined |
| Reopen | It is Done or Declined. Sets it back to Open, into Approvals. |
| Open LIN-123, Open #12 | It has an issue in Linear or GitHub |
| Delete | Always |
Accept and decline
| Action | Status | Trackers | Reporters |
|---|---|---|---|
| Accept | Planned | Opens an issue in every connected tracker that has none for it yet | No message |
| Decline | Declined | Closes any linked issue as canceled or not planned | No message |
The card leaves Approvals as soon as you press either button. If a tracker refuses the issue, the signal still moves to Planned and the tracker's error shows under Approvals, or in the sidebar on the signal's page. Accept never opens a second issue in a tracker that already has one for the signal.
Several at once
Tick the checkbox on a row, or on a group heading to take the whole group. A bar appears at the bottom with the count.
| Button | Does |
|---|---|
| Status | Sets one status on every selected signal |
| Priority | Sets one priority on every selected signal |
| Accept | Accepts each one. Reports "Accepted N.", "Skipped N already accepted." and "N could not reach a tracker." |
| Decline | Declines each one. Reports "Declined N." |
| Delete | Asks first, then deletes them |
| Clear selection | Unticks everything |
A signal counts as already accepted when it is past Open and has an issue in every connected tracker. Bulk Accept on a Planned signal that is missing an issue opens the missing one.
Status and priority
| Status | Means | Linked issue | Reporters |
|---|---|---|---|
| Open | Waiting in Approvals | Reopened or moved back to not started | No message |
| Planned | Accepted | Reopened or moved back to not started | No message |
| In progress | Being worked on | Moved to started | No message |
| In review | Being checked | Moved to started | No message |
| Done | Shipped | Completed or closed | Each gets one message |
| Declined | Not happening | Canceled or closed as not planned | No message |
Status also flows back from Linear and GitHub. The full mapping is under Issue trackers.
| Priority | The agent picks it when |
|---|---|
| Urgent | Nobody can use the product |
| High | Something important is unusable and there is no way around it |
| Medium | It gets in the way and there is a workaround |
| Low | It is a papercut |
The agent uses Medium when it does not pick one. A Linear issue carries the same priority.
A signal's page
Click a title to open the signal.
| Area | Contents |
|---|---|
| Header | The kind tag, the title, Edit, when it was filed, how many people reported it, and "Updated by" with a name and time |
| Status, Priority | Menus to change either |
| Actions | Go to thread. Accept and Decline while Open. Mark done until Done or Declined. Reopen once Done or Declined. A link to each tracker issue. Past Open with no issue, "No linked tracker issue." Delete. |
| Body | The write-up, rendered as Markdown |
| Also reported as | Titles of duplicates merged into it |
| Commits | Commits that may have fixed it, see Issue trackers |
| Reporters | One row per person, newest first, up to 50 |
A signal that was deleted or merged away shows "This signal was deleted or merged into another."
File a signal by hand
Press New signal at the top of the list.
| Field | Rules |
|---|---|
| Type | Bug or Suggestion. Default Bug. |
| Title | Required. Up to 120 characters. |
| Details (optional) | Markdown. Up to 4,000 characters. |
| Priority | Urgent, High, Medium or Low. Default Medium. |
Create adds it to Approvals with no reporters. A signal filed by hand skips the AI duplicate read and never opens a tracker issue on its own.
| Error | Cause |
|---|---|
Enter a title. | The title is empty |
Already on the list as "<title>". | A signal of the same kind has that title or alias. Only the 60 most recently updated signals that are not Declined are checked. |
Edit on a row or on the signal's page changes the title and details. Edits update any linked issue.
Reports
The Reporters section on a signal's page has one row per person, newest first, up to 50.
| Part | Contents |
|---|---|
| Name | Their name, their email, or "Customer #N" |
| Quote | What they said, up to 400 characters |
| Image glyph and count | Screenshots on the report |
| Thread ids | Each conversation they reported it from, for example W-12 |
| Page address | For a feedback panel note or a crash report, the page it was sent from, shown instead of thread ids. Reads "Feedback panel" or "Crash report" when no page was sent. |
| Time | When they reported it |
Click a row to open the report.
| Section | Contents |
|---|---|
| Header | "Reported" with the date, and " · Notified of completion" once they were told |
| Quote | Their words |
| From the feedback panel | Shown for panel notes |
| From a crash report | Shown for reports sent with reportError |
| Screenshots | Up to 6. Click one to open it full size. |
| Threads | Each conversation by id and subject |
| Facts | Page, Viewport, values from your app's state, and values you attached with context that are a single link. A link already shown as a screenshot is left out. |
| Browser logs | Error, Unhandled rejection, Console and Request entries |
| Attached values | Every other attached value, one block each under its label |
| Server check: Passed or Server check: Failed | What your diagnostics endpoint returned |
Copy report copies the whole report as plain text.
Screenshots
| Source | What lands on the report |
|---|---|
| A conversation | Images the customer sent in the thread. Only theirs, from the last 60 messages. |
| The agent | Image links the customer gave it |
| The feedback panel | Images picked, dragged or pasted in with the note |
| Your code | An image address passed to attach, or image links sent with POST /v1/feedback |
Each report keeps up to 6. Issues opened in Linear or GitHub show them inline.
Telling reporters
When a signal moves to Done, each reporter gets one message in the conversation they last reported from. It is posted under the agent's name.
| Kind | Message |
|---|---|
| Bug | This bug has been fixed. Thanks for reporting it. |
| Suggestion | Your suggestion has been implemented. Thanks for sending it. |
- Every move to Done sends it. That includes the list, the signal's page, the bulk bar, Confirm fix, a commit on a repository with Close bugs automatically, and the issue closing in Linear or GitHub.
- A reporter is messaged once. Reopening and marking Done again does not message them a second time.
- Feedback panel notes have no conversation, so they get no message. Neither does a report whose conversation was deleted.
- Declining and deleting send nothing.
- Reporters merged into a signal that is already Done get the message.
- Each message fires the
message.createdwebhook.
Merge duplicates
Merging has no button in the dashboard. Use the CLI, the API, MCP, or ask the assistant.
| Surface | Call |
|---|---|
| CLI | median signals merge <keep-id> --duplicate <remove-id> |
| API | POST /v1/signals/{id}/merge with { "duplicateId": "..." } |
| MCP | median.signals.merge({ signalId, duplicateId }) |
- The signal you name first survives. The duplicate is deleted.
- Reports move to the survivor. A person on both keeps one report.
- The duplicate's title becomes an alias under "Also reported as". A signal keeps up to 6.
- The survivor keeps the higher priority of the two.
- The survivor takes the duplicate's Linear or GitHub issue when it has none of its own.
- Commits claimed for the duplicate move to the survivor.
See the CLI reference and the management API for the full options.
Delete a signal
Delete asks for confirmation, then removes the signal with its reports and commit claims. Nobody is messaged. Issues in Linear or GitHub stay as they are.
New signals fire bug.created or suggestion.created, and changes fire
signal.updated. See Webhooks.