How nima decides
Every rule nima uses to classify signals, place them into beacons, rank beacons and decide when a beacon is ready.
nima makes four decisions without asking you: what kind of thing a signal is, where the signal belongs, how a beacon ranks, and when a beacon is ready for a person to look at. This page lists the rules behind each one, with the numbers.
On for every workspace. Classification, automatic beacon placement, ranking and readiness run for every workspace with no setting to turn on.
Two of the decisions are judgment calls by a language model: labeling a signal, and choosing whether a signal joins a beacon or starts a new one. Ranking and readiness are arithmetic.
Signal classification and impact
nima labels each signal with one classification and an impact after an extraction pass that runs shortly after the signal arrives. Until that pass finishes the signal has neither.
Eight classification labels exist, but nima's extractor only ever assigns three of them: bug, feature_request and spec_drift. The other five exist so a signal can carry them and you can filter on them.
| Classification | Assigned by nima's extractor | Meaning |
|---|---|---|
bug | Yes | Something is broken. |
feature_request | Yes | Someone wants something that does not exist. |
spec_drift | Yes | What shipped does not match what was specified. |
customer_feedback | No | An opinion or experience report without a specific ask. |
performance | No | Slowness, limits or resource problems. |
documentation | No | Something is unclear or undocumented. |
question | No | Someone is asking, not reporting. |
noise | No | Not product signal. |
Impact is low, medium or high. The extractor also pulls out stakeholders and product areas from the text. Impact and stakeholders feed the beacon rank.
Noise dismissal and the topics nima always keeps
nima dismisses a signal its extractor judges to be noise, with the dismiss reason noise, except when the signal's topics mention money or legal exposure. A signal whose product areas or intent mention any of these words is kept as actionable even if the model called it noise:
pricing, price, discount, compliance, soc 2, soc2, gdpr, hipaa, contract, contracts, terms, legal, msa, dpa, loi, success fee.
The rule is a fixed keyword check, not a model instruction. In a Slack channel set to auto-skip, a noise signal is dismissed with reason auto_skip and hidden from every signal list, including the dismissed ones.
Extraction limits per signal
nima runs extraction on a signal at most 3 times, ever, and stops once the cumulative model cost for that signal reaches USD 0.25. Every reply in the signal's Slack thread runs extraction again on the same signal, so a busy thread uses up that budget. The next attempt after either cap moves the signal to failed, even if an earlier run already classified it; the classification stays on the signal. A single extraction job is also cut off after 60 seconds.
Signal origin: internal, external or customer
Every signal carries an origin of internal, external or customer, which says whose words it is. nima infers the origin from the integration that produced the signal. Most sources are resolved when the signal is read; Granola, Linear, ClickUp and HubSpot decide the origin when they create the signal, from the attendees, the request type, the custom field or the account.
| Source | Origin |
|---|---|
| HubSpot | customer when the record's account is a customer or partner account, external for any other account. An import recipe can pin a source to internal or external instead. |
| GitHub | external |
| Slack, manual, Sentry, PostHog, webhook | internal |
| Granola | customer when any attendee's email domain differs from the domain of the person who connected the key; otherwise internal. |
| Linear | internal, except a Linear customer request, which is customer. |
| ClickUp | internal, except a task carrying a customer-named custom field, which is customer. |
HubSpot signal ingestion is rolling out; ask the nima team to turn it on for your workspace.
Attendees without an email address are ignored for Granola. If the person who connected the Granola key uses a free-mail address, every attendee at another domain counts as outside.
You can override the inferred origin on a single signal with PATCH /v1/signals/:id. That route needs a signed-in session (any member); API keys and MCP tokens get 403. There is no MCP tool or Slack action for it yet; ask the nima team if you only hold an API key. See Signals.
Placing a signal into a beacon
nima places each classified signal that is not already in a beacon (status ready) on its own, in a background pass that starts about 60 seconds after signals arrive. A pass handles at most 25 signals, oldest first, and schedules another pass when it filled up and placed something.
The pass has two steps for each signal.
- Shortlist by similarity. Open beacons whose evidence is similar to the signal at cosine similarity
0.45or higher become candidates, at most 6. Held, promoted and dismissed beacons are never candidates. - A model judge chooses. The judge answers
join(one of the offered beacons),form(start a new beacon, titled as an imperative) ordismiss. Its instruction is: when unsure, form. Ajointhat names a beacon that was not offered becomesform.
dismiss currently has no effect on the signal. nima turns it into form, so a signal the judge would drop still gets a beacon.
Signals that carry an incident fingerprint skip the judge. An error report with the same fingerprint and scope as an existing repair beacon joins that beacon, including a held beacon or a promoted one whose spec has not shipped yet. Otherwise it starts a new fix beacon.
A signal belongs to at most one beacon. Adding it to another beacon moves it, except that a signal behind a promoted beacon cannot be moved.
Automatic placement is a workspace-wide behavior, and nima does not merge signals or beacons on its own. Manually created signals are not de-duplicated either: filing the same text twice creates two signals.
Beacon disposition: fix or decide
nima stamps every beacon it forms with a disposition. fix means the evidence describes something plainly broken with no product decision left. decide covers everything else and is the default when nima is unsure. Disposition is a label on the beacon, and it is what nima's optional auto-promotion looks at (see What nima does not do automatically).
Beacon rank formula
A beacon's rank is a whole number from 0 to 100, recomputed whenever its evidence changes. It is not recomputed on a schedule, so recency reflects the last time the beacon's evidence changed, not today.
The formula:
score = round(100 × (0.35·severity + 0.30·reach + 0.20·weight + 0.15·recency))| Term | Coefficient | How nima computes it |
|---|---|---|
severity | 0.35 | Highest impact among member signals: high 1.0, medium 0.6, low or unset 0.3. |
reach | 0.30 | min(1, distinct stakeholders ÷ 6), where a stakeholder is an account or person extraction named, or the person who reported a member signal, each counted once. It saturates at six. |
weight | 0.20 | Mean producer weight across the beacon's evidence, one entry per evidence event. |
recency | 0.15 | max(0.1, 1 − days since the newest evidence ÷ 30). |
Producer weight by source
Producer weight says how much a source counts as evidence. A production error tracker outweighs a remark in Slack.
| Source | Key | Weight |
|---|---|---|
| Sentry, PostHog, inbound webhook | sentry, posthog, webhook | 0.80 |
| Manual entry, HubSpot | manual, hubspot | 0.70 |
| GitHub | github | 0.60 |
| Slack | slack | 0.50 |
| Every other source, including Granola, Linear and ClickUp | any other key | 0.50 |
Worked example of a beacon rank
Four signals about one checkout failure, each with a single event: two Slack messages, one manual entry, one Sentry issue. One is high impact. Four distinct stakeholders in all, counting the people who reported each signal. The newest evidence is three days old.
severity = 1.0 (one high-impact member)
reach = 4 ÷ 6 = 0.667 (four distinct stakeholders)
weight = (0.5 + 0.5 + 0.7 + 0.8) ÷ 4 = 0.625
recency = 1 − 3 ÷ 30 = 0.900
score = round(100 × (0.35×1.0 + 0.30×0.667 + 0.20×0.625 + 0.15×0.900))
= round(100 × (0.350 + 0.200 + 0.125 + 0.135))
= 81The same four signals as Slack messages at medium impact, naming two people, ten days old, score 51. Raising the highest-impact member from medium to high adds 14 points.
When a beacon becomes ready
A beacon moves from forming to ready by one of three paths, and which one applies depends on how the beacon was created.
| How the beacon was created or what it carries | When it becomes ready |
|---|---|
| Opened by nima's placement judge | Immediately, with any number of signals and any rank. |
| Carries an urgent incident | Immediately. |
| Grouped by a person | When it has at least 3 distinct member signals and rank is 70 or higher. |
An urgent incident is an open (not recovered) incident triage record with an error, severity critical, high or fatal, and outcome failed, terminal_failure, retry_exhausted, data_loss or unavailable.
For a person-grouped beacon, having 3 distinct signals marks the beacon as formed. That mark latches: removing evidence later does not un-form it. Three events on one signal count as one piece of evidence.
Held, promoted and dismissed beacons never change status when nima refreshes them, whatever their rank does.
| Status | Meaning |
|---|---|
forming | Collecting evidence, not yet flagged. |
ready | Waiting for a person to decide. |
held | Parked by a person, with a reason. |
promoted | A spec was generated from it (the status changes when generation finishes). |
dismissed | Rejected. |
The Grouping setting (Signals per beacon)
The Signals per beacon control under Grouping in the admin panel no longer affects anything. nima stores the value (beaconMinClusterSize, 2 or 3) but placement does not read it: the model judge and the rules above decide. Changing it does not change how signals group.
What nima does not do automatically
nima does not merge signals, merge beacons, start specs or dismiss beacons in a normal workspace. Three behaviors exist in the code but are off, and only the nima team can switch them on for the platform:
- Auto-promote. For a
fixbeacon, nima would start the spec itself, up to 3 per pass, under the workspace owner. - Auto-dismiss. The judge's
dismissanswer would park a non-ask on a beacon bornheld. Todaydismissbecomesform. - Daily and ship sweeps. A daily pass would hold suspected duplicate beacons and non-asks, and a shipped spec would hold the open beacons asking for what it delivered. Only a person could confirm a merge or dismissal.
In production, nima writes a spec only when a person promotes a beacon. See Anatomy of a spec.
Changing an outcome after nima decides
You can correct a decision, but only through signed-in session routes on the REST API. There is no MCP tool and no Slack action for any of these yet, and they need a signed-in session (any member); API keys and MCP tokens get 403. Ask the nima team if you only hold an API key.
- Signals. Edit classification, impact, stakeholders and origin with
PATCH /v1/signals/:id, dismiss or restore a signal, and merge signals by hand. - Beacons. Hold (a reason is required), dismiss, merge beacons, and add or remove member signals. Removing every member leaves an empty beacon instead of deleting it.
Impact and stakeholders are rank inputs, but editing them does not recompute the beacon on its own: the new values count the next time the beacon is refreshed, for example when a member is added or removed. A beacon stores its rank breakdown term by term, so you can see which term moved. Routes and scopes are on Signals and Beacons.
The loop: Signal to Closed
nima's five-stage pipeline, where each stage is worked today (Slack, MCP, API), what nima does on its own and the one human gate.
Anatomy of a spec
How nima writes a spec from a beacon: research, the decision pause, the required sections, bug-repair specs, and how to read or edit the result.