Site: Planekeeper Docs — Monitor software versions across your stack. Planekeeper tracks releases, gathers version data, and alerts on drift.
Section: Reference > Rule types
Source: https://docs.planekeeper.com/reference/rule-types/
Title: Rule types
Author: Planekeeper
Description: Detailed reference for each rule type — days behind, majors behind, and minors behind — including threshold configuration, stable-only filtering, and calculation examples.
Word count: 820
Reading time: 4 min

Contents:
- [How thresholds work](#how-thresholds-work)
- [Days behind](#days-behind)
- [Majors behind](#majors-behind)
- [Minors behind](#minors-behind)
- [Stable-only filtering](#stable-only-filtering)
- [Choosing the right rule type](#choosing-the-right-rule-type)

***

# Rule types


Rules define how Planekeeper measures version staleness. Each rule type calculates a "behind by" value and compares it against three severity thresholds you configure: moderate, high, and critical.

## How thresholds work

Every rule has three threshold tiers. Thresholds must be ordered from smallest to largest:

| Threshold | Severity | Meaning |
|-----------|----------|---------|
| `moderate` | Moderate | First level of concern |
| `high` | High | Significantly behind |
| `critical` | Critical | Immediate attention required |

The highest matching threshold wins. If the behind-by value is below the moderate threshold, no alert is generated.

**Example:** A rule with thresholds moderate=7, high=30, critical=90:

- Behind by 5 days: no alert
- Behind by 10 days: **moderate** alert
- Behind by 45 days: **high** alert
- Behind by 100 days: **critical** alert

---

## Days behind

Alerts when your deployed version was released more than N days ago, measured from the deployed version's release date to today.

**Parameter:** `max_days` (set via the three threshold fields)

**How it calculates:**

1. Look up the release date of your discovered (deployed) version in the upstream releases
2. Calculate the number of days between that release date and today (`time.Since(deployedReleaseDate)`)
3. Compare against your thresholds

The latest version's release date is not used in this calculation. Only the deployed version's release date and the current date matter.

**Example (assuming today is Mar 15):**

| Your version | Released on | Days since release (to today) | Behind by |
|-------------|------------|-------------------------------|-----------|
| 1.25.0 | Jan 29 | 45 days | 45 days |
| 2.0.0 | Mar 10 | 5 days | 5 days |
| 3.1.0 | Dec 6 | 99 days | 99 days |

With thresholds of moderate=30, high=60, critical=90:

- Version 1.25.0: 45 days since release = **moderate**
- Version 2.0.0: 5 days since release = no alert
- Version 3.1.0: 99 days since release = **critical**

> **warning:** 
**Version not found**

If your deployed version does not exist in the upstream releases (for example, a custom build or fork), Planekeeper marks it as **critical** with a behind-by value of -1. Update your gather job configuration to ensure the deployed version appears in the release list.


---

## Majors behind

Alerts when your deployed version is N or more major versions behind the latest release.

**Parameter:** `max_majors` (set via the three threshold fields)

**How it calculates:**

1. Parse both your deployed version and the latest version as semantic versions
2. Subtract the major version numbers: `latest_major - deployed_major`

**Example:**

| Your version | Latest version | Calculation | Behind by |
|-------------|----------------|-------------|-----------|
| 1.5.2 | 3.1.0 | 3 - 1 | 2 majors |
| 2.0.0 | 2.9.5 | 2 - 2 | 0 majors |
| 5.3.1 | 8.0.0 | 8 - 5 | 3 majors |

With thresholds of moderate=1, high=2, critical=3:

- Version 1.5.2 vs 3.1.0: 2 majors behind = **high**
- Version 2.0.0 vs 2.9.5: 0 majors behind = no alert
- Version 5.3.1 vs 8.0.0: 3 majors behind = **critical**

> **warning:** 
**Parse failures**

If either version string cannot be parsed as a semantic version (for example, `latest` or `nightly-build`), the alert is marked **critical** with a behind-by value of -1. Use version transforms on your scrape job to normalize version strings into semver format.


---

## Minors behind

Alerts when your deployed version is N or more minor releases behind the latest. This rule counts actual releases, not version number gaps.

**Parameter:** `max_minors` (set via the three threshold fields)

**How it calculates (preferred method):**

1. Collect all upstream releases between your deployed version and the latest
2. Count unique `major.minor` combinations in that range
3. Use that count as the behind-by value

This means skipped version numbers do not inflate the count. If a project releases 1.1, 1.2, 1.5, and 1.8 (skipping 1.3, 1.4, 1.6, 1.7), only four minor releases are counted.

**Example with release-list counting:**

Available releases: 2.0.0, 2.1.0, 2.2.0, 2.3.0, 2.4.0, 3.0.0, 3.1.0

| Your version | Latest | Unique minors between | Behind by |
|-------------|--------|----------------------|-----------|
| 2.2.0 | 3.1.0 | 2.3, 2.4, 3.0, 3.1 | 4 minors |
| 2.4.0 | 3.1.0 | 3.0, 3.1 | 2 minors |
| 3.0.0 | 3.1.0 | 3.1 | 1 minor |

**Fallback calculation:**

When the full release list is unavailable, Planekeeper uses a formula:

- Same major version: `latest_minor - deployed_minor`
- Different major versions: `(latest_major - deployed_major) + latest_minor`

This is an approximation and may overcount when major version boundaries are crossed.

---

## Stable-only filtering

Enable the **stable_only** flag on a rule to ignore prereleases when determining the latest version. When enabled, Planekeeper skips any release whose version string contains:

`alpha`, `beta`, `rc`, `dev`, `snapshot`, `canary`, `nightly`, `pre`

The check is case-insensitive, so `1.0.0-RC1`, `2.0.0-beta.3`, and `3.0.0-SNAPSHOT` are all treated as prereleases.

**Example:**

Available releases (newest first): 5.0.0-rc1, 4.2.0, 4.1.0, 4.0.0

| stable_only | Latest version used | Notes |
|------------|-------------------|-------|
| Off | 5.0.0-rc1 | Compares against the prerelease |
| On | 4.2.0 | Skips the RC, uses the latest stable |

> **success:** 
**When to use stable_only**

Enable stable-only filtering when you track production deployments that should only follow stable releases. Leave it off if your deployment pipeline tracks release candidates or beta versions intentionally.


---

## Choosing the right rule type

| Scenario | Recommended rule type | Why |
|----------|----------------------|-----|
| Security-sensitive applications | `days_behind` | Time-based detection catches any stale version regardless of versioning scheme |
| Frameworks with breaking changes per major | `majors_behind` | Tracks the effort level of upgrading |
| Rapidly iterating projects | `minors_behind` | Counts actual releases you have missed |
| Mixed versioning strategies | Combine multiple rules | Create separate alert configs with different rule types for the same scrape+gather pair |


---

## Related

- Next: [Settings reference](https://docs.planekeeper.com/reference/settings-reference/page.md) — Reference for organization-level settings including default notification channels, template defaults, and task execution configuration.
- Section: [Reference](https://docs.planekeeper.com/reference/index.md)
