Monitors
Watch for something being true of a profile — a failing import, a card about to expire, nobody seen for a fortnight — with dwell, resolution and recurrence.
A monitor watches for a condition being true of a profile. It trips when the condition has held for as long as you say, resolves when it stops holding, and can trip again next month.
The test for whether you want one: does it un-happen? A monitor is for something that can stop being true, and whose number is therefore a stock — how many are open right now. Its mirror is the milestone, which is for something that sticks: it fires once, never un-fires, and its number is a rate over the profiles that could have reached it.
That is the only thing the two doors decide. A monitor is not a synonym for a problem — most are, and you want those lists empty, but you also say so explicitly. Every signal carries a Is firing good news? setting, so "trial is actively converting" is a perfectly good monitor that you want full, and "hit the hard seat cap" is a milestone you would rather nobody reached. Same machinery underneath — dwell, deduplication, observe mode — and the same form.
Every member can read monitors. Only workspace admins can create, edit, promote, pause, archive or delete them. Monitors live on a stage's page, in the section below its milestones — the same place, and the same editor, as the thing they mirror.
What a monitor is for
Four shapes it catches:
- Something is true right now that will not stay true — an import is failing, an integration is disconnected, a trial is converting. True today, false tomorrow, true again next month.
- Something is about to happen — a card expires in nine days, a renewal is in thirty.
- Nothing is happening — no session in fourteen days, a second user was never invited. Nothing happening emits nothing, so only a scheduled scan catches it. Uptend already runs one after every sync.
- Something changed shape — sessions down 60% against this profile's own thirty-day baseline, which means the same thing at two seats and at two thousand.
Where monitors live
Open a stage — Activation, Retention, Expansion or Reactivation — and click its Signals tab. It carries two lists: Milestones, whose numbers are rates, and Monitors, whose numbers are counts of what is open. Each list has its own Add a … footer, and both open the same editor. The stage's Overview is left to read the stage; Signals is where you define it.
Whether you want a given list full or empty is not a property of the list. A row marked good under Monitors is one you want open; a row marked problem under Milestones is one you would rather stayed at zero.
lifecycle-stage-monitorsEach row shows how many trips opened inside the window, how many are open right now, and a View trips link to the monitor's own page. A monitor in observe reads its window count as "N would have tripped", because that is all it did.
The window — 30, 90, 180 or 365 days — applies to when a trip opened, like the stage overviews: a window on events, not on when profiles signed up.
A monitor belongs to one stage
A monitor watches the stage it was written on, and only that stage. There is no stage picker and no list of stages to tick: the page you opened the sheet from is the answer.
Some conditions do read as though they are not about a stage — "not seen for a fortnight" is true wherever a profile sits. Write those on the stage where you would actually act on them. If a second stage needs the same watch, write it there too; the two roll up separately, which is usually what you wanted from the stage page anyway.
Good news or bad
Every signal — milestone or monitor — carries one setting: Is firing good news?
| Setting | What it changes |
|---|---|
| Good — progress | Counts towards the stage's progress rate. Its number reads high-is-good, and open episodes show in green, marked good. |
| Bad — a problem | Left out of the stage's progress rate. Its number reads high-is-bad, and while it is open it appears on the profile's open problems card. |
The door you came through sets the default — a milestone starts as progress, a monitor as a problem — and you can change it. Two combinations are worth knowing about:
- A good monitor. "Trial is actively converting", "power-user streak holding". It opens, it resolves, and you want the list full. It is deliberately kept off the profile's open-problems card, because it is not one.
- A problem milestone. "Hit the hard seat cap", "downgraded past the point of no return". It latches once and never un-latches, so it is a milestone — but its rate is a count of people affected, not a rate of progress, so it is excluded from the stage's own progress number and reads in red.
Every monitor starts out observing
A monitor has three statuses:
| Status | What it does |
|---|---|
| Observing | Evaluated normally; trips are recorded and shown, labelled observed only. Nothing downstream hears about it. |
| Active | Trips are real: they raise events, and lifecycle rules can read this monitor. |
| Paused | Not evaluated at all. Open trips stay open until you resume it. |
Every monitor is created in observe. Read the list of what it would have caught, then promote it with Promote beside the row, or Promote to active on the monitor's page. A monitor in observe that a lifecycle rule references reads as never tripped, so nothing moves by surprise.
A new workspace starts with no monitors at all, exactly as it starts with no milestones. What is worth watching for in your product is the one thing we cannot guess, and three plausible-looking defaults reading placeholder property keys were worse than an empty list that says so.
Create a monitor
- Open the stage it belongs to, go to its Signals tab and click Add a monitor in the Monitors list.
- Name it. The key is derived from the name and cannot be changed later.
- Say whether firing is good news. It defaults to a problem, which is what most monitors are.
- Build the condition with the same guided builder every rule uses. One condition is unavailable here on purpose: a monitor cannot read another monitor.
- Set who could trip it and how long it must hold (both below).
- Click Run preview, then Create.
lifecycle-new-monitorThe condition
The builder offers the same conditions every rule does — a Property comparison and Days since a date — plus two shapes monitors need most:
- Date coming up — the date stored in a property falls within the next N days: "the card expires in the next nine days". A date already in the past does not satisfy it; that is Days since.
- Against a baseline — one property divided by another, optionally scaled, compared to a number:
projects_7d ÷ (projects_30d ÷ 4.29) < 0.4is "this week is under 40% of the profile's own 30-day run rate". The scale is what makes two different windows comparable (30 ÷ 7 ≈ 4.29). A missing or zero baseline never satisfies it — absent is not bad.
Every condition asks something about the profile itself. There is nothing to pick that reads the lifecycle state, because the monitor's scope already decides which states it sees — asking for Churned on a monitor scoped to Retention would simply never trip — and nothing that is unconditionally true, because a monitor that trips everything in scope is a scope, not a condition.
A condition that nests beyond what the builder shows is edited as JSON, the same fallback every rule editor offers.
Watching a number instead of a rule
A monitor does not have to watch a rule. Instead of A rule that becomes true, pick:
- A number on the move — a number property plus what counts as a move: any change, a change of at least an amount or a percentage, or crossing one of your own lines.
- A step along an ordered list — a tier property plus its rungs, listed lowest first.
Then say which way is forward: the direction you want the value to go. Up for seats or projects, down for open tickets or failed jobs. A monitor opens an episode when the value moves the other way, and resolves only when it gets back to where it started — not merely when it stops moving. So:
- Forward is up on seats: the episode opens when seats fall, and closes when they are back at the number they fell from.
- Forward is down on open tickets: the episode opens when tickets climb, deepens if they climb further, and closes when the count comes back down to where it was.
A partial recovery keeps the episode open, which is the point — "seats fell from 100 to 25 and are back to 30" is still a problem. Must hold for works here too: "tickets went up and stayed up for two days".
The In words box under the form spells the result out in a sentence. Read it before you save; three settings — the kind of thing you came in for, which way is forward, and whether firing is good news — are independent, and the sentence is the only place all three are stated together.
Who could trip it
Only some profiles could reach this is the denominator — the same control a milestone uses, and new to monitors. Without it, a monitor's rate is "of everyone being watched", which is usually not the question: a monitor about seat count means nothing for a profile that has no seats. Switch it on and the rule you write decides who is even eligible to trip.
Scope decides where a trip may open, not where the monitor lives. A profile that changes stage while a trip is open keeps that trip until the condition is false, so a stage change never quietly closes a webhook that is still broken.
Dwell
Must hold for is how long the condition must stay true before a trip opens, in minutes. Zero trips on the first cycle the condition holds. A dwell of a day means one quiet Sunday against a busy month is not a drop — the condition falling false before the dwell runs out opens nothing at all.
Preview
Run preview is a dry run of the next cycle under the draft, writing nothing: how many profiles would be tripped, how many are holding out the dwell, how many are fine, and how many match but are out of scope. On an existing monitor the preview reads the saved state, so "would be tripped" means "after this save" — which is what makes it a preview rather than a count.
A monitor's page
lifecycle-monitor-detailFour numbers over the window:
- Incidence — profiles with a trip that opened in the window.
- Time to resolve — the median from open to resolved, for the trips that closed in the window.
- Repeat trippers — profiles that have tripped more than once, ever. A condition that keeps coming back is a different conversation from one that happened once.
- Open now — trips waiting on somebody. For an observing monitor, trips that raised nothing.
Then the trips table: open trips first, then the ones resolved inside the window, each with the values the condition read when it opened — a trip nobody can explain is a trip nobody acts on.
Editing, pausing and archiving
Click a monitor's name on the stage page to reopen the same sheet you created it in. A change to the condition, the denominator, the dwell or the scope creates a new version and re-evaluates every profile on the next cycle — including restarting any dwell that was part-way through, because time measured against a condition that no longer exists is not evidence. A rename or a status change does not.
Pause stops evaluation and leaves open trips open. Archive stops evaluation and resolves the open trips in the same breath — an archived monitor with an open trip would be a problem nobody is watching. A monitor that has never tripped can be deleted outright; one with trips is history, so archive it instead.
Trips on a profile
A profile with open trips carries an Open trips card above its lifecycle state and scores: the monitor, the values it read and how long it has been open. The timeline records A monitor tripped and A monitor resolved beside the threshold crossings — with how long it was open, and labelled when the monitor was only observing.
What monitors do not do yet
A trip is detection and a record. Sending anything — an operator alert, a customer email, a Slack message, a sequence — waits for the automation layer, and so do quiet hours, frequency caps and the daily brief. Today a monitor answers "is this true, since when, and how often", which is the question the profile page and the timeline both want to read whether or not anything is ever sent. Lifecycle rules can already read a monitor's state as a condition.