Promotion Policies¶
Promotion policies boost an entity's decay score when specific conditions are met. They contain logic: FOR targets, APPLY blocks with ON ACCESS mutations, and WHEN predicates that select promotion profiles.
Architecture¶
Promotion has two components:
- Promotion Profiles — named parameter bundles declaring multiplier, score floor, score cap (no logic, no targets)
- Promotion Policies — targeted bindings with
FOR,APPLY,ON ACCESS, andWHENclauses
Creating a Promotion Profile¶
Promotion profiles contain no logic — they are parameter bundles referenced by name inside promotion policy APPLY blocks:
CREATE PROMOTION PROFILE reinforced_tier OPTIONS {
multiplier: 1.5,
scoreFloor: 0.3,
scoreCap: 1.0
}
| Parameter | Default | Description |
|---|---|---|
multiplier | 1.0 | Score multiplier. >1.0 boosts, 1.0 is neutral, <1.0 dampens. A multiplier of 0.5 halves the decayed score; combined with an inverted decay profile (negative halfLifeSeconds) this implements "punish frequent access" semantics where hot nodes are demoted. See Inverted Decay. |
scoreFloor | 0.0 | Minimum score AFTER the multiplier is applied. Different from the decay bundle's scoreFloor — this one acts inside the promoted-curve computation (max(promoFloor, base * multiplier)), the bundle's floor acts as the final clamp on the result. Neither is a visibility cutoff; the suppression check is visibilityThreshold on the decay bundle. |
scoreCap | 1.0 | Maximum score after promotion |
The decay pipeline is
final = max(decayBundle.scoreFloor, min(promoProfile.scoreCap, max(promoProfile.scoreFloor, base * multiplier))), thensuppressed = final < decayBundle.visibilityThreshold. The promotion floor only matters when the matchingWHENpredicate fires; the decay floor matters always. Pick the right floor for the right job.
Creating a Promotion Policy¶
CREATE PROMOTION POLICY <name>
FOR (<target>)
APPLY {
ON ACCESS {
<mutations>
}
WHEN <predicate>
APPLY PROFILE '<profile_name>'
}
Example: Basic Tiered Promotion¶
CREATE PROMOTION POLICY session_record_tiering
FOR (n:SessionRecord)
APPLY {
ON ACCESS {
SET n.accessCount = coalesce(n.accessCount, 0) + 1
SET n.lastAccessedAt = timestamp()
}
WHEN n.accessCount >= 3
APPLY PROFILE 'reinforced_tier'
WHEN n.accessCount >= 5 AND n.sourceAgreement >= 0.95
APPLY PROFILE 'canonical_tier'
}
Example: Negative Multiplier (Access Dampening)¶
A multiplier below 1.0 dampens the score for entities that hit a hot-path threshold. Pairs with an inverted decay profile to invert the recency bias: frequently-accessed entries are demoted, idle entries strengthen over time. See the full walkthrough in Inverted Decay.
CREATE PROMOTION PROFILE access_dampener OPTIONS {
multiplier: 0.5,
scoreFloor: 0.0,
scoreCap: 1.0
}
CREATE PROMOTION POLICY hot_path_dampening
FOR (n:Memory)
APPLY {
ON ACCESS {
SET n.accessCount = coalesce(n.accessCount, 0) + 1
SET n.lastAccessedAt = timestamp()
}
WHEN n.accessCount >= 5
APPLY PROFILE 'access_dampener'
}
Example: Kalman-Filtered Behavioral Signals¶
CREATE PROMOTION POLICY episodic_recall_quality
FOR (n:MemoryEpisode)
APPLY {
ON ACCESS {
SET n.accessCount = coalesce(n.accessCount, 0) + 1
SET n.lastAccessedAt = timestamp()
WITH KALMAN{q: 0.05, r: 50.0} SET n.confidenceScore = $evaluatedConfidence
WITH KALMAN SET n.crossSessionAccessRate =
CASE WHEN n._lastSessionId <> $_session
THEN coalesce(n.crossSessionAccessRate, 0) + 1
ELSE n.crossSessionAccessRate
END
SET n._lastSessionId = $_session
SET n._lastAgentId = $_agent
}
WHEN n.accessCount >= 5 AND n.confidenceScore >= 0.8
APPLY PROFILE 'high_confidence_tier'
WHEN n.accessCount >= 3
APPLY PROFILE 'reinforced_tier'
}
ON ACCESS Semantics¶
ON ACCESS mutations execute when the target entity is accessed and passes the suppression gate. Key rules:
- Mutations apply exclusively to the accessMeta index, never to the target node/edge itself
- Property reads (e.g.,
n.accessCount) resolve from accessMeta first, then fall back to stored properties - Suppressed entities (score below visibility threshold) do not accumulate access state
WHENpredicates read persisted + buffered accessMeta state from prior accesses
WITH KALMAN¶
The WITH KALMAN clause applies Kalman filtering to smooth behavioral signals:
| Parameter | Description |
|---|---|
q | Process noise covariance (how much the true value changes between observations) |
r | Measurement noise covariance (how noisy observations are) |
When q and r are omitted, defaults are used. Kalman filtering is appropriate for derived behavioral metrics (access rates, confidence scores) — not for ground-truth values.
Query Context Variables¶
ON ACCESS blocks can access query context variables projected from request headers:
| Request Header | Available As | Purpose |
|---|---|---|
X-Query-Session | $_session | Same-session deduplication |
X-Query-Agent | $_agent | Agent provenance tracking |
Listing and Dropping¶
SHOW PROMOTION POLICIES;
DROP PROMOTION POLICY session_record_tiering;
DROP PROMOTION PROFILE reinforced_tier;
Dropping a promotion profile that is still referenced by an active policy produces a validation error.
See Also¶
- Knowledge-Layer Policies — System overview
- Decay Profiles — Defining decay behavior
- Visibility Suppression — Suppression and deindex behavior
- Ebbinghaus-Roynard Bootstrap — Complete working example with promotion policies and Kalman filtering