| name | persona-heartbeat |
| description | Ambient monitoring and health pulse for AI Persona OS sessions. Monitors context window usage, provides proactive suggestions when advisor mode is enabled, detects session starts to resume previous work, performs silent memory maintenance (pruning old entries, archiving logs), and surfaces health status when needed. Trigger keywords: heartbeat, monitor, pulse, context check, health, session start, memory maintenance, ambient, housekeeping, status check, session resume, context health.
|
| allowed-tools | ["Bash","Read","Write","Glob"] |
Persona Heartbeat
Ambient monitoring and health pulse system for AI Persona OS. This skill handles procedural context health checks, proactive suggestion surfacing, session resumption, and memory maintenance.
Phase 1: Context Health Check
Purpose: Monitor context window usage and trigger appropriate actions based on thresholds.
Step 1.1: Determine Current Context Usage
Check the current context window usage percentage through available system metrics.
context_usage_pct = get_context_window_usage()
computed.context_level = context_usage_pct
Step 1.2: Apply Threshold Logic and Surface User-Facing Messages
Based on context usage, determine what the user sees and what actions to take:
| Usage Range | User-Facing Behavior |
|---|
| < 50% | Nothing — healthy operation |
| 50-69% | Nothing — note internally for tracking |
| 70-84% | "📝 Context at [X]% — saving checkpoint before continuing." then delegate to persona-checkpoint |
| 85-94% | "🟠 Context at [X]% — emergency checkpoint saved. Consider starting a new session soon." |
| 95%+ | "🔴 Context at [X]% — critical. Saving essentials. Please start a new session." |
if context_usage_pct >= 95:
show_critical_warning()
save_essential_state()
computed.action_taken = "critical_checkpoint"
elif context_usage_pct >= 85:
show_emergency_warning()
delegate_to_checkpoint()
computed.action_taken = "emergency_checkpoint"
elif context_usage_pct >= 70:
show_checkpoint_notice()
delegate_to_checkpoint()
computed.action_taken = "standard_checkpoint"
else:
computed.action_taken = "none"
Step 1.3: Record Threshold Crossing Events
Track when thresholds are crossed to avoid repeat notifications within the same session.
if computed.action_taken != "none":
timestamp = current_timestamp()
append_to_session_log(threshold_event, timestamp)
Phase 2: Proactive Suggestion Engine
Purpose: Surface helpful suggestions when advisor mode is enabled, following strict rules to avoid noise.
Activation Condition: Only when advisor mode is ON in USER.md.
Step 2.1: Check Advisor Mode Status
user_config = read_file("~/workspace/USER.md")
advisor_enabled = parse_advisor_mode(user_config)
computed.advisor_active = advisor_enabled
Step 2.2: Evaluate Suggestion Criteria
Only surface suggestions when ALL conditions are met:
- Significant new context about user goals discovered
- Spotted unnoticed pattern or opportunity
- Time-sensitive opportunity present
- No complex task currently in progress
- Max 1 suggestion per session not exceeded
- Previous suggestion not ignored/rejected
if not advisor_enabled:
return # Skip suggestion engine entirely
suggestion_contexts = [
"new_goal_context",
"unnoticed_pattern",
"time_sensitive_opportunity"
]
blockers = [
"complex_task_active",
"session_quota_exceeded",
"previous_ignored"
]
if any_suggestion_context() and not any_blocker():
computed.suggestion_eligible = true
else:
computed.suggestion_eligible = false
Step 2.3: Format and Surface Suggestion
Format:
💡 SUGGESTION
[One sentence describing what was noticed]
[One sentence proposing action]
Want me to do this? (yes/no)
Example:
{
"questions": [
{
"question": "💡 SUGGESTION\n\nI noticed you've created three similar scripts in the last hour with overlapping functionality.\n\nWould you like me to consolidate them into a reusable module?\n\nWant me to do this?",
"key": "suggestion_response",
"options": ["yes", "no"]
}
]
}
if computed.suggestion_eligible:
formatted_suggestion = format_suggestion(context, proposal)
response = ask_user(formatted_suggestion)
if response == "yes":
execute_suggested_action()
computed.suggestion_accepted = true
else:
log_suggestion_declined()
computed.suggestion_accepted = false
mark_session_suggestion_quota_used()
Phase 3: Session Start Detection
Purpose: Detect new sessions and resume previous work context silently.
Step 3.1: Detect First Message in New Session
is_session_start = detect_new_session()
computed.is_new_session = is_session_start
if not is_session_start:
return # Skip session start procedures
Step 3.2: Load Core Persona Files Silently
Read foundational files without surfacing content to user.
soul_content = read_file("~/workspace/SOUL.md")
user_content = read_file("~/workspace/USER.md")
memory_content = read_file("~/workspace/MEMORY.md")
computed.persona_loaded = true
Step 3.3: Check for Yesterday's Log
yesterday_date = get_yesterday_date() # Format: YYYY-MM-DD
log_path = "~/workspace/memory/daily-{yesterday_date}.md"
if file_exists(log_path):
yesterday_log = read_file(log_path)
computed.has_previous_log = true
else:
computed.has_previous_log = false
Step 3.4: Surface Uncompleted Items or Stay Silent
if computed.has_previous_log:
uncompleted_items = parse_uncompleted_items(yesterday_log)
if uncompleted_items:
surface_resumption_message(uncompleted_items)
# Example: "📋 Resuming from last session:
# • Fix authentication bug in login flow
# • Review PR #42 for dependency updates"
else:
# Nothing to surface — silent operation
pass
else:
# No previous log — silent operation
pass
Phase 4: Memory Maintenance
Purpose: Perform silent housekeeping on memory files and logs, notifying only when action is taken.
Trigger: Every ~10 exchanges (approximate, not strict).
Step 4.1: Check MEMORY.md Size
memory_file = "~/workspace/MEMORY.md"
file_size = get_file_size(memory_file)
computed.memory_size_kb = file_size / 1024
if computed.memory_size_kb > 4:
computed.memory_needs_pruning = true
else:
computed.memory_needs_pruning = false
Step 4.2: Prune Old Memory Entries
Remove entries older than 30 days if file exceeds 4KB.
if computed.memory_needs_pruning:
cutoff_date = current_date() - 30_days
memory_entries = parse_memory_entries(memory_file)
entries_to_keep = filter(lambda e: e.date >= cutoff_date, memory_entries)
pruned_count = len(memory_entries) - len(entries_to_keep)
if pruned_count > 0:
write_file(memory_file, entries_to_keep)
computed.pruned_entries = pruned_count
else:
computed.pruned_entries = 0
Step 4.3: Archive Old Daily Logs
Move logs older than 90 days to archive directory.
log_directory = "~/workspace/memory/"
archive_directory = "~/workspace/memory/archive/"
daily_logs = glob(log_directory + "daily-*.md")
cutoff_date = current_date() - 90_days
logs_to_archive = []
for log in daily_logs:
log_date = parse_date_from_filename(log)
if log_date < cutoff_date:
logs_to_archive.append(log)
if logs_to_archive:
ensure_directory_exists(archive_directory)
for log in logs_to_archive:
move_file(log, archive_directory)
computed.archived_logs = len(logs_to_archive)
else:
computed.archived_logs = 0
Step 4.4: Check for Uncompleted Items from Previous Days
recent_logs = get_logs_from_last_7_days("~/workspace/memory/")
uncompleted_items = []
for log in recent_logs:
items = parse_uncompleted_items(log)
uncompleted_items.extend(items)
if uncompleted_items and not already_surfaced_this_session():
surface_once_per_session(uncompleted_items)
computed.surfaced_uncompleted = true
else:
computed.surfaced_uncompleted = false
Step 4.5: Notify Only When Action Taken
actions_taken = []
if computed.pruned_entries > 0:
actions_taken.append(f"Pruned {computed.pruned_entries} old memory entries")
if computed.archived_logs > 0:
actions_taken.append(f"Archived {computed.archived_logs} old daily logs")
if actions_taken:
notification = "🗂️ Housekeeping: " + ", ".join(actions_taken) + "."
display(notification)
else:
# Silent operation — no notification
pass
Phase 5: Heartbeat Output Format
Purpose: Standardized format for surfacing health status to user.
Step 5.1: Determine When to Surface Heartbeat
Surface heartbeat status when:
- Explicitly requested by user ("heartbeat", "status", "health check")
- Context threshold crossed (70%+)
- Housekeeping actions taken
- Uncompleted items found at session start
Step 5.2: Format Heartbeat Header
current_datetime = get_current_datetime() # Format: 2026-02-17 14:30
model_name = get_current_model() # e.g., "claude-opus-4-6"
version = "1.0.0" # AI Persona OS version
header = f"🫀 {current_datetime} | {model_name} | AI Persona OS v{version}"
Step 5.3: Generate Traffic Light Indicators
Determine health indicators with blank lines between each:
indicators = []
# Context health
if computed.context_level < 70:
indicators.append("🟢 Context: {computed.context_level}% (healthy)")
elif computed.context_level < 85:
indicators.append("🟡 Context: {computed.context_level}% (attention recommended)")
else:
indicators.append("🔴 Context: {computed.context_level}% (action required)")
# Memory health
if computed.memory_size_kb < 4:
indicators.append("🟢 Memory: {computed.memory_size_kb}KB (healthy)")
elif computed.memory_size_kb < 8:
indicators.append("🟡 Memory: {computed.memory_size_kb}KB (attention recommended)")
else:
indicators.append("🔴 Memory: {computed.memory_size_kb}KB (action required)")
# Advisor status
if computed.advisor_active:
indicators.append("🟢 Advisor: Active")
else:
indicators.append("⚪ Advisor: Inactive")
# Uncompleted items
if computed.surfaced_uncompleted:
indicators.append("🟡 Uncompleted: Items pending from previous sessions")
Step 5.4: Assemble and Display Heartbeat
heartbeat_output = header + "\n\n" + "\n\n".join(indicators)
display(heartbeat_output)
Example Output:
🫀 2026-02-17 14:30 | claude-opus-4-6 | AI Persona OS v1.0.0
🟢 Context: 45% (healthy)
🟢 Memory: 2.8KB (healthy)
🟢 Advisor: Active
⚪ Uncompleted: None
Notes
- This skill operates primarily in the background, with most phases running silently
- Only surface information when it provides value to the user
- Respect the max 1 suggestion per session rule strictly
- Memory maintenance should not interrupt active work
- Heartbeat format provides quick visual health assessment