> ## Documentation Index
> Fetch the complete documentation index at: https://docs.helmkit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Signals

> Complete reference of the conditions Triage watches for — what each signal detects, how its priority works, and what makes an entry clear

export const PriorityLabel = ({level, showLabel = true}) => {
  let label = "";
  let color = "";
  let svg = null;
  switch (level) {
    case "none":
      label = "None";
      color = "#71717a";
      svg = <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" style={{
        width: "1em",
        height: "1em",
        flexShrink: 0
      }}>
          <rect x="2" y="10.75" width="5" height="2.5" rx="1.25" fill="currentColor" />
          <rect x="9.5" y="10.75" width="5" height="2.5" rx="1.25" fill="currentColor" />
          <rect x="17" y="10.75" width="5" height="2.5" rx="1.25" fill="currentColor" />
        </svg>;
      break;
    case "low":
      label = "Low";
      color = "#71717a";
      svg = <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" style={{
        width: "1em",
        height: "1em",
        flexShrink: 0
      }}>
          <rect x="2" y="14.5" width="5" height="7.5" rx="1.5625" fill="currentColor" />
          <rect x="9.5" y="8.25" width="5" height="13.75" rx="1.5625" fill="currentColor" opacity="0.2" />
          <rect x="17" y="2" width="5" height="20" rx="1.5625" fill="currentColor" opacity="0.2" />
        </svg>;
      break;
    case "medium":
      label = "Medium";
      color = "#3f3f46";
      svg = <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" style={{
        width: "1em",
        height: "1em",
        flexShrink: 0
      }}>
          <rect x="2" y="14.5" width="5" height="7.5" rx="1.5625" fill="currentColor" />
          <rect x="9.5" y="8.25" width="5" height="13.75" rx="1.5625" fill="currentColor" />
          <rect x="17" y="2" width="5" height="20" rx="1.5625" fill="currentColor" opacity="0.2" />
        </svg>;
      break;
    case "high":
      label = "High";
      color = "#d97706";
      svg = <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" style={{
        width: "1em",
        height: "1em",
        flexShrink: 0
      }}>
          <rect x="2" y="14.5" width="5" height="7.5" rx="1.5625" fill="currentColor" />
          <rect x="9.5" y="8.25" width="5" height="13.75" rx="1.5625" fill="currentColor" />
          <rect x="17" y="2" width="5" height="20" rx="1.5625" fill="currentColor" />
        </svg>;
      break;
    case "urgent":
      label = "Urgent";
      color = "#dc2626";
      svg = <svg aria-hidden="true" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="none" style={{
        width: "1em",
        height: "1em",
        flexShrink: 0
      }}>
          <path d="M20 2C21.1046 2 22 2.89543 22 4V20C22 20.8629 20.8629 22 20 22H4C3.13706 22 2 20.8629 2 20V4C2 3.13706 3.13706 2 4 2H20ZM12.0281 15.6206C11.3225 15.6206 10.75 16.1919 10.75 16.8975C10.75 17.603 11.3225 18.1755 12.0281 18.1755H12.0623C12.7678 18.1755 13.3403 17.603 13.3403 16.8975C13.3403 16.1919 12.7678 15.6206 12.0623 15.6206H12.0281ZM12.0452 5.75C11.3976 5.75 10.8721 6.27554 10.8721 6.9231V9.40723C10.8721 10.6387 11.04 12.0024 11.1772 13.2793C11.225 13.7231 11.5988 14.063 12.0452 14.063C12.4914 14.0629 12.8641 13.723 12.9119 13.2793C13.0491 12.0024 13.217 10.6387 13.217 9.40723V6.9231C13.217 6.2756 12.6926 5.75009 12.0452 5.75Z" fill="currentColor" />
        </svg>;
      break;
    default:
      return null;
  }
  return <span style={{
    display: "inline-flex",
    alignItems: "center",
    gap: "0.25em",
    verticalAlign: "middle",
    lineHeight: 1,
    color,
    marginTop: "-2px",
    fontWeight: 500
  }}>
      {svg}
      {showLabel && <span style={{
    color: "inherit"
  }}>{label}</span>}
    </span>;
};

## How to read this page

Triage watches for a fixed set of **signals** — named conditions across your organization's data. Each section below describes one signal, grouped by the kind of thing it watches. For each signal, you'll see:

* **What it detects** — the plain-English condition that makes an entry appear.
* **Priority** — either a flat level, or *escalating*: priority climbs as the run gets closer. See [the escalation curve](/features/preflight/triage#how-urgency-works) for how the time-based levels work.
* **Time anchor** — the date Triage uses to sort the entry and decide whether it falls inside your time horizon. Usually this is the linked run's start date; for action items, it's the item's due date.
* **What clears it** — the specific actions that make the entry disappear.

Every signal is enabled by default. Admins can turn any of them off for the whole organization under **Settings → Organization → Triage** — see [Filters & views](/features/preflight/triage/filters-and-views#turning-signals-on-or-off) for details.

## Action items

<AccordionGroup>
  <Accordion title="Overdue action items">
    **What it detects:** Action items past their due date that aren't marked done or cancelled.

    **Priority:** Always <PriorityLabel level="urgent" />. An item past due is as critical as it gets — there's no "slightly overdue" bucket.

    **Time anchor:** The item's due date.

    **What clears it:**

    * Mark the item <strong>Done</strong> or <strong>Cancelled</strong>
    * Push the due date to a future time
    * Delete the item
    * Snooze it (personal only — others still see it)
  </Accordion>

  <Accordion title="Unassigned action items">
    **What it detects:** Open action items (Todo or In progress) with no one on the recipient list. Nobody is accountable, so nothing will move them forward.

    **Priority:**

    * If the item has a due date: escalating via the default curve (<PriorityLabel level="low" /> → <PriorityLabel level="urgent" /> as the deadline approaches).
    * If the item has no due date: flat <PriorityLabel level="medium" />.

    **Time anchor:** The due date, if set. Otherwise none — the item shows regardless of the time horizon.

    **What clears it:**

    * Assign the item to one or more people
    * Mark it <strong>Done</strong> or <strong>Cancelled</strong>
    * Delete the item
  </Accordion>

  <Accordion title="Assigned to me">
    **What it detects:** Open action items where you personally are on the recipient list. This is "my work" — the lens you'll land on by default as a non-admin.

    **Priority:** Uses the item's own priority field (you set it when creating the item). If the item's priority is left at "None," Triage falls back to the time-driven escalation curve so time-boxed items still rise to the top.

    **Time anchor:** The item's due date, if set.

    **What clears it:**

    * Mark the item <strong>Done</strong> or <strong>Cancelled</strong>
    * Remove yourself from the recipients
    * Delete the item
  </Accordion>
</AccordionGroup>

## Runs

<AccordionGroup>
  <Accordion title="No guide assigned">
    **What it detects:** Upcoming runs with no accepted guide. Triggers for runs that have never been invited to a guide, for runs where every invitation was rejected or cancelled, and for runs where invitations are still pending.

    **Priority:** Escalating via the default curve. A run a month out sits at <PriorityLabel level="low" />; the week before, <PriorityLabel level="high" />; the last 48 hours, <PriorityLabel level="urgent" />.

    **Time anchor:** The earliest active (non-cancelled) booking's start time.

    **What clears it:**

    * A guide accepts an invitation for the run
    * The run's bookings are all cancelled
    * The run's earliest booking moves to the past
  </Accordion>

  <Accordion title="Missing tickets">
    **What it detects:** Upcoming runs on a rate flagged "Requires tickets" where no ticket has been uploaded yet. One entry per run, not per booking — tickets attach to the run as a whole.

    **Priority:** Escalating via the default curve.

    **Time anchor:** The earliest active booking's start time.

    **What clears it:**

    * Upload at least one ticket to the run
    * Flip the rate's "Requires tickets" setting off (see [Filters & views](/features/preflight/triage/filters-and-views#configuring-requires-tickets))
    * The run's earliest booking moves to the past

    <Note>
      This signal only fires on rates you've explicitly marked as requiring
      tickets. If you've never enabled it, you'll never see the signal — it's
      safe to leave on.
    </Note>
  </Accordion>

  <Accordion title="Over capacity">
    **What it detects:** Runs whose total booking count has exceeded the rate's configured capacity. Helm tracks this as a first-class run status, so the signal is always in sync with what you'd see on the run detail view.

    **Priority:** Flat <PriorityLabel level="high" />. Over-capacity is an immediate operational issue regardless of timing — you can't double-book the boat.

    **Time anchor:** The earliest booking's start time.

    **What clears it:**

    * Increase the rate's capacity
    * Move one or more bookings to a different run
    * Cancel enough bookings to fit within capacity
  </Accordion>

  <Accordion title="Inconsistent runs">
    **What it detects:** Runs flagged as inconsistent, usually because the bookings on the run have diverging information — different start times, different pax counts, different pickup details — that need a human to resolve.

    **Priority:** Escalating via the default curve. Earlier in the cycle you have time to investigate calmly; closer to the run, it's urgent.

    **Time anchor:** The earliest booking's start time.

    **What clears it:**

    * Resolve the conflicts (unmerge bookings, cancel the conflicting one, or update details so they line up)
    * The run's earliest booking moves to the past
  </Accordion>
</AccordionGroup>

## Guide invitations

<AccordionGroup>
  <Accordion title="Pending guide invites">
    **What it detects:** Guide invitations that were sent but haven't been accepted or rejected yet.

    **Priority:** Escalating via the default curve. A pending invite three weeks out is <PriorityLabel level="medium" />; the week before, <PriorityLabel level="high" />; 48h before, <PriorityLabel level="urgent" />.

    **Time anchor:** The linked run's earliest booking start time.

    **What clears it:**

    * The guide accepts the invitation
    * The guide rejects the invitation (this moves the entry to the **Rejected guide invites** signal instead)
    * You cancel the invitation
    * The run moves to the past
  </Accordion>

  <Accordion title="Rejected guide invites">
    **What it detects:** Guide invitations that were explicitly rejected. Requires re-inviting the same guide (with different terms, usually) or inviting someone else.

    **Priority:** Flat <PriorityLabel level="high" />. A rejection is an immediate staffing gap regardless of how far out the run is.

    **Time anchor:** The linked run's earliest booking start time.

    **What clears it:**

    * Send a new invitation (which supersedes the rejected one)
    * Another guide accepts a different invitation for the same run
    * You cancel or delete the rejected invitation
    * The run moves to the past
  </Accordion>
</AccordionGroup>

## Integrations

<AccordionGroup>
  <Accordion title="Integration sync failures">
    **What it detects:** Third-party connections (currently WooCommerce) whose recent sync health is reported as degraded or unhealthy.

    **Priority:** Flat <PriorityLabel level="high" />. A failing integration affects data freshness across the whole organization, not just one run.

    **Time anchor:** None — this signal has no date. It's always shown regardless of the time horizon filter, and stays until the integration recovers.

    **What clears it:**

    * A subsequent sync succeeds and the health check flips back to healthy
    * The integration is disconnected from the organization

    <Tip>
      If you're seeing this signal repeatedly on the same integration, check the
      connection's settings under **Settings → Integrations**. The detail panel
      in Triage links straight there.
    </Tip>
  </Accordion>
</AccordionGroup>
