# OPENCLAW_TRICKS.md — Configuration Recipes for OpenClaw Agents A collection of tested patterns, prompts, and file structures for configuring an OpenClaw agent as a proactive personal assistant. These are extracted from a production setup that's been running since early 2026. --- ## Table of Contents 1. [Workspace Bootstrapping](#workspace-bootstrapping) 2. [Daily Context — The State File](#daily-context--the-state-file) 3. [Sitrep (Situation Report)](#sitrep-situation-report) 4. [Sleep Tracking](#sleep-tracking) 5. [Location & Timezone Tracking](#location--timezone-tracking) 6. [Medication Tracking](#medication-tracking) 7. [Flight & Travel Logging](#flight--travel-logging) 8. [Landing Checklist](#landing-checklist) 9. [Memory Architecture](#memory-architecture) 10. [Heartbeat Configuration](#heartbeat-configuration) 11. [Gitea Integration & Notification Polling](#gitea-integration--notification-polling) 12. [Sub-Agent Management](#sub-agent-management) 13. [Urgent Notifications via ntfy](#urgent-notifications-via-ntfy) 14. [Group Chat Behavior](#group-chat-behavior) 15. [Cron vs Heartbeat — When to Use Each](#cron-vs-heartbeat) 16. [Requirement Capture](#requirement-capture) --- ## Workspace Bootstrapping Your workspace is the agent's home directory. Core files: ``` workspace/ ├── AGENTS.md # Responsibilities, rules, procedures ├── SOUL.md # Personality, tone, values ├── USER.md # Info about your human (name, tz, prefs) ├── IDENTITY.md # Agent's own identity ├── HEARTBEAT.md # What to check on heartbeat polls ├── MEMORY.md # Curated long-term memory ├── TOOLS.md # Environment-specific notes (hosts, keys, devices) └── memory/ ├── daily-context.json ├── YYYY-MM-DD.md # Daily raw notes ├── sleep-log.csv ├── location-log.csv ├── flight-log.csv ├── medications-log-YYYY-MM.csv ├── medications-instructions.md ├── landing-checklist.md ├── checklist-*.md # Various operational checklists └── heartbeat-state.json ``` ### Session startup prompt (put in AGENTS.md): ```markdown ## Every Session Before doing anything else: 1. Read `SOUL.md` — this is who you are 2. Read `USER.md` — this is who you're helping 3. Read `memory/daily-context.json` — current state (location, timezone, sleep, meds) 4. Read `memory/YYYY-MM-DD.md` (today + yesterday) for recent context 5. **If in MAIN SESSION** (direct chat with your human): Also read `MEMORY.md` Don't ask permission. Just do it. ``` This ensures the agent always has context on wake. The key insight is that the agent wakes up fresh every session — files ARE its memory. --- ## Daily Context — The State File This is the single most important file. It's a JSON blob that every session reads on every message. It tracks the current state of your human. ### Schema: `memory/daily-context.json` ```json { "isSleeping": false, "lastKnownWakeTime": "2026-02-28T12:30:00+07:00", "predictedSleepTime": "2026-03-01T05:30:00+07:00", "predictedWakeTime": "2026-03-01T12:45:00+07:00", "hasTakenDailyMedsToday": false, "dailyMedsTimestamp": "2026-02-27T11:43:00+07:00", "lastCaffeineTimestamp": null, "currentLocation": "City (IATA)", "currentTimezone": "Asia/Bangkok", "currentLodging": "Hotel Name", "travelLeg": "Description of current travel phase", "nearestAirport": "ICAO code", "lastMessageFromUser": "2026-02-28T05:20:00+07:00", "lastMessageChannel": "mattermost", "isAvailable": true, "lastUpdated": "2026-02-28T06:00:00+07:00", "lastSleep": "actual: 2026-02-28 05:15-12:30 ICT (~7h15m). Stable pattern." } ``` ### AGENTS.md prompt: ```markdown ## Daily Context Stored in `memory/daily-context.json`. All agents: review on every conversation/message to detect if any state has changed. Update the JSON file directly. ``` ### Why it works: - Every session reads this first, so the agent always knows where you are - Sleep predictions help the agent decide when to alert vs stay quiet - Medication timestamps enable overdue detection - Timezone field means the agent always converts times correctly - `lastMessageFromUser` lets the agent infer activity gaps = sleep --- ## Sitrep (Situation Report) The sitrep is triggered by a keyword (e.g. "sitrep") and produces a concise status briefing. The key design feature is that the agent can **add sections dynamically** based on what it thinks you should know. ### AGENTS.md prompt: ```markdown ### Sitrep (Situation Report) When the user says "sitrep", provide a concise summary covering: 1. **Daily meds** — taken today or not 2. **Interval meds** — any due/overdue or upcoming in next 48h. ALWAYS include "X days from now" countdown. ALWAYS include day of week. 3. **Open issues assigned to me** — count 4. **Open issues assigned to user** — count + brief summary 5. **Upcoming travel** — flights in next 72h with times/airports. ALWAYS also include the next known flight even if beyond 72h. 6. **Upcoming appointments** — next 48h 7. **Todo list** — overdue, due today, due tomorrow (separate categories) 8. **Unbooked travel** — flights that need booking. Flag deadlines. 9. **Sleep conflicts** — appointments in next 48h that fall within predicted sleep window 10. **Sleep** — one-line summary of last sleep + drift trend + concerns 11. **Unanswered questions** — questions the agent asked that haven't been answered 12. **Weather alerts** — only if significant or extreme. Use METAR from aviationweather.gov. Omit if nothing notable. 13. **Overdue reminders** — anything pending 14. **Open projects** — one-line status per project Before generating a sitrep, review the last 3 days of daily memory files for context. **If anything notable isn't covered by the items above — recent lessons, pending decisions, things you think the user should know about — add additional sections as needed.** Omit any item that is "none" or zero. Keep it scannable. Use bullet points, not prose. Only surface things the user might not know about or needs to act on. ``` ### Key design decisions: - **"Add additional sections as needed"** — this is the magic line. It lets the agent surface things you didn't think to ask about. If there's a pending decision from 2 days ago, or a lesson from a recent mistake, it'll include it. - **"Omit any item that is none or zero"** — keeps it clean. No "Overdue reminders: none" clutter. - **Relative times** ("4 days from now, Tuesday") are more useful than bare dates - **Review last 3 days** ensures the agent has recent context, not just today - The sitrep pulls from multiple data sources (daily context, calendars, issue trackers, memory files) — it's a dashboard in prose form ### Time display tip: ```markdown Include current time in local timezone, UTC, and any other relevant timezone at the top. ``` This anchors the reader and makes all the relative times unambiguous. --- ## Sleep Tracking The agent infers sleep from message activity gaps, not from explicit "I'm going to sleep" statements (though those help too). ### File: `memory/sleep-log.csv` ```csv Date,SleepTime,WakeTime,TimeZone,Duration,Status,Notes 2026-02-07,08:30,15:30,America/Los_Angeles,7h00m,actual,Approximate times 2026-02-08,~12:00,~15:30,America/Los_Angeles,~3h30m,actual,Short sleep ``` ### AGENTS.md prompt: ```markdown ### Sleep Tracking - **`memory/sleep-log.csv`** — columns: Date, SleepTime, WakeTime, TimeZone, Duration, Status, Notes - Infer sleep/wake times from message activity and explicit statements - User's sleep pattern drifts later each day; typical duration 4–8 hours - Update daily-context.json isSleeping field accordingly - **On every message from user:** if there was a communication gap overlapping predicted sleep time, infer a sleep window (sleep start = last activity before gap, wake = first activity after gap). Activity includes direct messages, git commits/comments, scheduled flight departures, and any other observable actions — not just chat messages. Log based on observed gaps only, never from mathematical predictions. ``` ### Daily context fields for sleep: ```json { "isSleeping": false, "lastKnownWakeTime": "2026-02-28T12:30:00+07:00", "predictedSleepTime": "2026-03-01T05:30:00+07:00", "predictedWakeTime": "2026-03-01T12:45:00+07:00", "lastSleep": "actual: 2026-02-28 05:15-12:30 ICT (~7h15m). Stable pattern." } ``` ### How prediction works: The agent observes the pattern drift (e.g., sleeping 30min later each day) and extrapolates. Predictions are updated after each actual observation. The agent uses predictions to: - Avoid sending non-urgent alerts during predicted sleep - Flag sleep conflicts with upcoming appointments in sitreps - Factor caffeine intake into predictions (caffeine = 5-6h minimum awake) ### Caffeine integration: ```json { "lastCaffeineTimestamp": "2026-02-10T00:45:00-08:00" } ``` Track caffeine in daily-context.json. If the user has caffeine, adjust sleep prediction forward by their typical caffeine-to-sleep duration. --- ## Location & Timezone Tracking The agent always knows where you are and adjusts all time displays accordingly. ### File: `memory/location-log.csv` ```csv Date,City,Country,Timezone 2026-02-08,Las Vegas,US,America/Los_Angeles 2026-02-11,Berlin,DE,Europe/Berlin 2026-02-18,Bangkok,TH,Asia/Bangkok ``` ### Timezone rules (AGENTS.md): ```markdown ## Timezone/Time Rules - System clock is PST. User's TZ is in daily-context.json — always convert. - "Today"/"tomorrow" = user's local TZ, not system clock. - Never state times without explicit conversion. - When logging medication times, always use the user's current timezone. ``` ### Why this matters: OpenClaw runs on a server (probably in a fixed timezone). Your human travels. Without explicit timezone tracking: - "Take your meds" fires at 3am local time - "Today" means the wrong day - Sleep predictions are off by hours - Calendar events show wrong times The daily-context.json `currentTimezone` field is the single source of truth. Everything else derives from it. --- ## Medication Tracking This is a safety-critical system. The design prioritizes never missing a dose and never double-dosing over convenience. ### Files: - `memory/medications-instructions.md` — the authoritative medication list, dosages, schedules, and safety rules - `memory/medications-log-YYYY-MM.csv` — one row per ingestion, split by month - `memory/checklist-medications.md` — pre-action verification checklist ### Log format: `memory/medications-log-YYYY-MM.csv` ```csv Date,Time,TimeZone,Medication,Dosage 2026-02-27,11:43,Asia/Bangkok,Metoprolol,50 mg 2026-02-27,11:43,Asia/Bangkok,Omeprazole,40 mg 2026-02-27,11:43,Asia/Bangkok,Aspirin,162 mg ``` ### Instructions file structure (`memory/medications-instructions.md`): ```markdown # Medication Instructions ## General Rules - Maintain cumulative CSV logs split by month as the authoritative record - CSV columns (fixed order): Date,Time,TimeZone,Medication,Dosage - "Today"/"yesterday"/"tomorrow" always mean relative to currentTimezone in daily-context.json — NEVER relative to system clock - Always spell medication names correctly; silently correct transcription errors ## Daily Medications One batch per calendar day unless explicitly confirmed otherwise. "Log my daily meds" = log each as a separate row. **CRITICAL: Never trust hasTakenDailyMedsToday without verifying dailyMedsTimestamp.** - Resolve the current date in user's currentTimezone FIRST - Check if dailyMedsTimestamp falls on THAT date in THAT timezone - If the timestamp is from a previous calendar day, meds are NOT taken today regardless of the boolean **Ideal dosing window:** every 24h ±4h. Hard minimum: 14h between doses. | Medication | Dosage | | ------------ | ------ | | (your meds) | (dose) | ## Interval-Based Medications Scheduling anchored to last actual dose, NOT intended dates. | Medication | Dosage | Interval | | ---------- | ------ | ------------ | | (med name) | (dose) | Every X days | **Missed dose rules:** - If missed, next dose date is unknown until the missed dose is taken and logged - Interval restarts from actual ingestion timestamp - Missed doses block future scheduling ## Safety Rules (HIGHEST PRIORITY) 1. Always triple-check before instructing any medication: - Last actual dose taken - Required dosing interval - Current eligibility without overdose risk 2. If any ambiguity exists, **do not instruct dosing** 3. Immediately block logging if same-day duplicate daily-med batch or other overdose pattern appears 4. Require explicit confirmation in any overdose-risk scenario ``` ### Verification checklist (`memory/checklist-medications.md`): ```markdown # Medications Checklist ## Before reporting medication status 1. Check medications-log-YYYY-MM.csv for actual entries, not dailyMedsTimestamp 2. Verify dailyMedsTimestamp is from today in user's timezone (not system clock) 3. Cross-reference medications-instructions.md for what's due ## Before sending medication reminders 1. Confirm current time in user's timezone 2. Check if already taken today (verify against CSV, not boolean) 3. For interval meds: calculate days since last dose from CSV 4. Never send PII (medication names) via public notification channels ``` ### Overdue escalation: ```markdown **CRITICAL: If daily meds are >26h since last dose, escalate aggressively.** Use urgent notification channel if chat messages go unacknowledged. Do not let this slide silently. Always include hours since last dose in reminders (e.g. "daily meds overdue — last dose was 27h ago"). ``` ### Why the double-check on the boolean: The daily-context.json has a `hasTakenDailyMedsToday` boolean AND a `dailyMedsTimestamp`. A midnight-reset cron flips the boolean to false. But if the user is in a timezone ahead of the server, the boolean may reset before their actual "today" ends — or after it began. The rule: **always verify the timestamp falls on today's date in the user's timezone.** The boolean is a convenience hint, not the source of truth. --- ## Flight & Travel Logging ### Files: - `memory/flight-log.csv` — one row per flight segment - `memory/location-log.csv` — one row per calendar day - `memory/travel.md` — upcoming travel plans, booking status - `memory/checklist-flights.md` — pre-action checklist ### Flight log format: ```csv Date,FlightNumber,Origin,Destination,Duration,Alliance 2026-02-10,DL9670,LAS,AMS,10h10m,SkyTeam 2026-02-10,KL1856,AMS,BER,1h25m,SkyTeam ``` ### Flight prep blocks (put in HEARTBEAT.md): ```markdown ## Flight Prep Blocks (daily) Run `khal list today 7d`. For flights missing "shower and dress" / "travel to airport" blocks, create them: - shower_start = flight_departure - airport_buffer - travel_buffer - 1h - Airport buffer: 2h domestic, 2.5h international - Travel to airport: 1h default - Create "shower and dress" block at shower_start (1h duration) - Create "travel to airport" block after shower - Set cron reminders: 15min before shower start, at departure time - Skip layover connections (already in airport) ``` This means the agent automatically works backwards from flight times to create preparation blocks in the calendar. No manual planning needed. --- ## Landing Checklist Triggered automatically after every flight lands. The agent doesn't wait to be asked. ### File: `memory/landing-checklist.md` ```markdown # Landing Checklist Run this after EVERY flight, regardless of whether location/timezone changes. ## Immediate (within minutes of landing) - [ ] Update daily-context.json → currentLocation, currentLodging, currentTimezone, nearestAirport, travelLeg - [ ] Update midnight-reset cron job timezone to new currentTimezone - [ ] Update location-log.csv with new city for today - [ ] Log flight segment in flight-log.csv ## Within 1 hour - [ ] Check if daily meds are due/overdue (timezone change may shift the window) - [ ] Check if any interval meds are due today - [ ] Sync calendar and review next 48h for the new timezone - [ ] Check for any cron jobs with hardcoded timezones that need updating ## If entering a new country - [ ] Check for medication resupply needs - [ ] Note any upcoming reminders that reference the old timezone ``` ### AGENTS.md prompt: ```markdown ### Landing Checklist - After EVERY flight the user takes, run through `memory/landing-checklist.md` - Trigger: calendar event landing time, or user messages after a flight - Do not wait to be asked — run it proactively ``` --- ## Memory Architecture The two-tier memory system: daily files (raw) + MEMORY.md (curated). ### Daily files: `memory/YYYY-MM-DD.md` Raw logs of what happened each day. Topics discussed, decisions made, tasks completed. Every session can read these. ```markdown # 2026-02-28 ## Topics | Time | Topic | Session | |------|-------|---------| | 14:30 | Discussed PR review workflow | main | | 16:00 | Medication logged | main | ## Notes - Decided to switch deployment strategy for project X - User prefers Y approach over Z — standing rule ``` ### MEMORY.md — Long-term curated memory ```markdown ## 🧠 MEMORY.md - Your Long-Term Memory - **ONLY load in main session** (direct chats with your human) - **DO NOT load in shared contexts** (group chats, sessions with others) - This is for **security** — contains personal context that shouldn't leak - Write significant events, thoughts, decisions, opinions, lessons learned - This is your curated memory — the distilled essence, not raw logs - Over time, review daily files and update MEMORY.md with what's worth keeping ``` ### Memory maintenance (in AGENTS.md or HEARTBEAT.md): ```markdown ### 🔄 Memory Maintenance (During Heartbeats) Periodically (every few days), use a heartbeat to: 1. Read through recent memory/YYYY-MM-DD.md files 2. Identify significant events, lessons, or insights worth keeping long-term 3. Update MEMORY.md with distilled learnings 4. Remove outdated info from MEMORY.md that's no longer relevant Think of it like reviewing a journal and updating a mental model. Daily files are raw notes; MEMORY.md is curated wisdom. ``` ### Critical rule — write it down: ```markdown ### 📝 Write It Down - No "Mental Notes"! - **Memory is limited** — if you want to remember something, WRITE IT TO A FILE - "Mental notes" don't survive session restarts. Files do. - When someone says "remember this" → update memory file - When you learn a lesson → update AGENTS.md or relevant file - When you make a mistake → document it so future-you doesn't repeat it - **Text > Brain** 📝 ``` --- ## Heartbeat Configuration Heartbeats are periodic polls from OpenClaw. The agent can do background work or stay quiet. ### HEARTBEAT.md structure: ```markdown # HEARTBEAT.md ## Inbox Check (PRIORITY) (check notifications, issues, emails — whatever applies) ## Flight Prep Blocks (daily) (create calendar prep blocks for upcoming flights) ## Open Projects Review (check project status, take next steps, or ask if blocked) ## Workspace Sync (commit and push workspace changes) ## Rules - Post status updates to a designated channel, not the main chat - Update state files after any state change - If nothing needs attention, reply HEARTBEAT_OK ## Output Rules Never send internal thinking or status narration to user's DM. Output should be: - HEARTBEAT_OK (if nothing needs attention) - A direct question or alert (if action needed) - Work narration → send to a status channel via message tool ``` ### Tracking heartbeat state: `memory/heartbeat-state.json` ```json { "lastChecks": { "email": 1703275200, "calendar": 1703260800, "weather": null, "gitea": 1703280000 }, "lastWeeklyDocsReview": "2026-02-24" } ``` ### Heartbeat vs Cron: ```markdown **Use heartbeat when:** - Multiple checks can batch together - You need conversational context from recent messages - Timing can drift slightly (every ~30 min is fine) - You want to reduce API calls by combining periodic checks **Use cron when:** - Exact timing matters ("9:00 AM sharp every Monday") - Task needs isolation from main session history - You want a different model or thinking level for the task - One-shot reminders ("remind me in 20 minutes") ``` --- ## Gitea Integration & Notification Polling For self-hosted Gitea instances, you can set up a notification poller that injects Gitea events (issue assignments, PR reviews, @-mentions) into the agent's session. ### Workflow rules (HEARTBEAT.md / AGENTS.md): ```markdown ## Gitea Work Scope Find issues/PRs assigned to me or where I'm @-mentioned → do the work. - If @-mentioned with work but not assigned → assign myself, remove other assignees - When nothing is assigned to me, my Gitea work is done - PRs assigned to user = their queue, not my backlog Workflow: issue → branch → PR "(closes #X)" → review/rework → assign user when all checks pass + reviewed. ### Rules - Respond in the medium addressed: Gitea → Gitea comment, not chat - Before acting on ANY issue or PR: read ALL existing comments first - Never do work on a PR/issue that isn't assigned to you - Work done, no more needed → close the issue - Your part done, need feedback → unassign yourself, assign next person ``` ### Notification poller: A Python script that polls the Gitea notifications API and injects events into OpenClaw sessions. It runs via launchd/systemd. Ask me for the full source code if you want to set this up — I can share it (it's a general-purpose tool with no PII). --- ## Sub-Agent Management For complex coding tasks, spawn isolated sub-agents. ### Key rules: ```markdown ### Sub-Agent Git Isolation (MANDATORY) - NEVER let multiple sub-agents share the same git clone - Each sub-agent MUST clone to a unique temporary directory (e.g. `mktemp -d`) - When spawning, always instruct: `cd $(mktemp -d) && git clone . && ...` - Dirty working directories cause false CI results ### Sub-Agent PR Quality Gate (MANDATORY) - `make check` must pass with ZERO failures. No exceptions. - Pre-existing failures are YOUR problem. Fix them as part of your PR. - NEVER modify linter config to make checks pass. Fix the code. - Every PR must include full `make check` output - Rebase before and after committing - Never self-review ``` --- ## Urgent Notifications via ntfy For time-sensitive alerts when chat messages might go unacknowledged (e.g., overdue medications): ```markdown ## Urgent Notifications Send urgent messages via ntfy.sh: curl -d "MESSAGE HERE" ntfy.sh/YOUR-PRIVATE-TOPIC-ID Use this for time-sensitive alerts (overdue meds, critical issues, etc.). **Never send PII via ntfy.** Keep messages generic (e.g. "daily meds overdue" not medication names or personal details). ``` Create a random topic ID for your ntfy channel. The agent can `curl` to it directly. --- ## Group Chat Behavior Rules for when the agent is in group chats with multiple people: ```markdown ### Know When to Speak **Respond when:** - Directly mentioned or asked a question - You can add genuine value (info, insight, help) - Something witty/funny fits naturally - Correcting important misinformation **Stay silent when:** - Just casual banter between humans - Someone already answered the question - Your response would just be "yeah" or "nice" - The conversation is flowing fine without you **The human rule:** Humans don't respond to every message. Neither should you. Quality > quantity. ### React Like a Human Use emoji reactions naturally: - Appreciate something but don't need to reply → 👍, ❤️ - Something made you laugh → 😂 - Interesting/thought-provoking → 🤔, 💡 - Acknowledge without interrupting → ✅, 👀 One reaction per message max. ``` --- ## Requirement Capture Never lose a rule or preference your human states: ```markdown ### Requirement Capture (MANDATORY) - **Every single requirement, rule, preference, or instruction the user provides MUST be captured in the daily memory file immediately** - This includes: project rules, workflow preferences, corrections, new policies, technical decisions - If the user says something should be done a certain way, write it down in memory/YYYY-MM-DD.md AND in MEMORY.md if it's a standing rule - Nothing is to be missed. If in doubt, log it. ``` --- ## PII Output Routing — Audience-Aware Responses A critical security pattern: **the audience determines what you can say, not who asked.** If your human asks for a sitrep (or any PII-containing info) in a group channel, you can't just dump it there — other people can read it. ### AGENTS.md / checklist prompt: ```markdown ## PII Output Routing (CRITICAL) - NEVER output PII in any non-private channel, even if your human asks for it - If a request would produce PII (medication status, travel details, financial info, etc.) in a shared channel: send the response via DM instead, and reply in-channel with "sent privately" - The rule is: the audience determines what you can say, not who asked - This applies to: group chats, public issue trackers, shared Mattermost channels, Discord servers — anywhere that isn't a 1:1 DM ``` ### Why this matters: This is a real failure mode. If someone asks "sitrep" in a group channel and you respond with medication names, partner details, travel dates, and hotel names — you just leaked all of that to everyone in the channel. The human asking is authorized to see it; the channel audience is not. Always check WHERE you're responding, not just WHO asked. --- ## General Tips ### Bias toward action Don't ask blocking questions with obvious answers. Figure it out. Come back with results, not requests for permission. ### Checklists over trust For safety-critical operations (meds, deployments, external communications), maintain checklists in `memory/checklist-*.md` and reference them from AGENTS.md. The agent reads the checklist before acting. ### State repo Keep your workspace in a git repo that auto-syncs. This gives you version history and recovery: ```markdown ### State Repo - Commit and push workspace changes after any change - Push promptly — remote should reflect workspace in near-realtime - Auto-sync cron runs every 6h as a safety net ``` ### Error handling philosophy ```markdown ## On Errors When something goes wrong: 1. Identify what input caused the wrong output 2. Fix the input (rule, checklist, prompt, automation) 3. Move on No apologies. No promises. Fix the system. ``` ### Never weaken checks ```markdown ## On Integrity Never cheat. When a check fails, fix the code — don't weaken the check. When a test fails, fix the bug — don't loosen the assertion. When a linter flags something, fix the finding — don't suppress the rule. ``` --- _This document is a living reference. Patterns here have been tested in production and refined through real-world use._