Strategies
The AdaptationStrategy model and the built-in strategies - UI visibility, notifications, task complexity, interaction forgiveness, deferral, autonomy, and demand admission.
A strategy is a pure mapping from energy level to behavior configuration. The SDK doesn't dictate what happens at each level - it provides the state, and strategies decide what to do with it.
The model
interface AdaptationStrategy<TConfig> {
name: string
describe(level: EnergyLevel): string // human-readable summary
resolve(level: EnergyLevel): TConfig // compute the config for a level
}Strategies are pure functions with no side effects, so they're trivially composable - an app resolves several at once:
const ui = engine.resolve(uiVisibilityStrategy)
const notifications = engine.resolve(notificationStrategy)In React, useStrategy(strategy) resolves against the current level and re-renders on change. To write your own, see Authoring strategies.
The built-ins
uiVisibilityStrategy
Progressively simplifies interface chrome as energy drops. Resolves to a UIVisibilityConfig:
| Level | sidebar | tabBar | statusBar | toolbar | chrome opacity | content width | font scale |
|---|---|---|---|---|---|---|---|
100 | ✓ | ✓ | ✓ | ✓ | 1 | none | 1 |
75 | ✓ | ✓ | ✓ | ✓ | 0.7 | none | 1 |
50 | ✓ | ✓ | ✓ | ✓ | 0.4 | 90ch | 1 |
25 | - | - | - | ✓ | 0.1 | 80ch | 1.05 |
0 | - | - | - | - | 0.05 | 75ch | 1.1 |
At 0 the config also sets readOnlyCursor: true - rest mode is for consuming, not producing. The reference stylesheet implements this same table in CSS.
notificationStrategy
Reduces interruptions as energy drops. Resolves to a NotificationConfig:
| Level | visual | sound | vibration | batch interval | priority threshold |
|---|---|---|---|---|---|
100 | ✓ | ✓ | ✓ | immediate | all |
75 | ✓ | ✓ | - | immediate | all |
50 | ✓ | - | - | 5 min | high |
25 | ✓ | - | - | 15 min | critical |
0 | - | - | - | - | none |
This config is guidance on its own. The notification gate is the runtime that enforces it - including the guarantee that nothing below the threshold is dropped, only deferred.
taskComplexityStrategy
Caps the complexity of work worth surfacing, and suggests break cadence:
| Level | maxComplexity | suggestBreaks | break interval |
|---|---|---|---|
100 | complex | - | - |
75 | moderate | - | - |
50 | routine | ✓ | 45 min |
25 | simple | ✓ | 25 min |
0 | consumption | - | - |
Rest gets no break suggestions on purpose: prompting someone at 0 to take a break from resting is noise.
interactionForgivenessStrategy
Lower energy means slower error detection, so forgiveness scales inversely with capacity - longer undo windows, confirmation on destructive actions, more frequent autosave:
| Level | undo window | confirm destructive | autosave every |
|---|---|---|---|
100 | 5s | - | 60s |
75 | 8s | - | 45s |
50 | 10s | ✓ | 30s |
25 | 15s | ✓ | 20s |
0 | 20s | ✓ | 15s |
deferralStrategy
Orders the "not now" presets by level so a one-tap defer matches capacity. Resolves to { orderedPresetIds, defaultPresetId }:
| Level | default deferral |
|---|---|
100 | in 1 hour |
75 | in 1 hour |
50 | this evening |
25 | tomorrow morning |
0 | tomorrow morning |
At low energy the default is "tomorrow morning", not "in 1 hour" - items should resurface when capacity has plausibly recovered.
autonomyStrategy
How much latitude automation has to act without asking. The mirror of interactionForgivenessStrategy: forgiveness protects against the user's mistakes at low energy, autonomy against the agent's. Resolves to an AutonomyConfig:
| Level | confidence threshold | generated content | max unattended steps |
|---|---|---|---|
100 | 0.6 | ✓ | 8 |
75 | 0.7 | ✓ | 5 |
50 | 0.8 | ✓ | 3 |
25 | 0.9 | templates only | 1 |
0 | 1.0 | templates only | 1 |
What narrows as energy falls is discretion, not action. At rest the automation may still take a single, certain, template-only step - the system acts on the user's behalf precisely when they are least able to supervise it, so the worst day is the wrong day for it to improvise.
demandAdmissionStrategy
Who gets through to the user, and what happens to everyone else. Resolves to a DemandAdmissionConfig; the full model, including acknowledgments, lives in Inbound demand.
| Level | originator threshold | acknowledge the rest | detail |
|---|---|---|---|
100 | all | - | full |
75 | known | ✓ | full |
50 | exempt | ✓ | full |
25 | exempt | ✓ | brief |
0 | exempt | ✓ | minimal |
Nothing is dropped at any level. What changes is whether demand reaches the inbox now or is acknowledged and queued - and how much the acknowledgment says.
createPresenceStrategy is an eighth export in this family, but it is a factory: you hand it a presence map and it returns a strategy for that map. See Presence.
describe() - explaining behavior to users
Every strategy can explain itself at any level, which is useful for settings screens and onboarding:
notificationStrategy.describe(50)
// "Steady: Only high priority, batched every 5min"Full strategy reference: /docs/api/core.
