implement repo policies: Makefile, Dockerfile, CI, prettier, editorconfig, LICENSE
Some checks failed
check / check (push) Failing after 9s
Some checks failed
check / check (push) Failing after 9s
Add failure stories section to OPENCLAW_TRICKS.md covering 10 real production failures and fixes from the first three weeks of operation.
This commit is contained in:
parent
c700721806
commit
f65ea86e4b
1
.dockerignore
Normal file
1
.dockerignore
Normal file
@ -0,0 +1 @@
|
||||
.git
|
||||
12
.editorconfig
Normal file
12
.editorconfig
Normal file
@ -0,0 +1,12 @@
|
||||
root = true
|
||||
|
||||
[*]
|
||||
indent_style = space
|
||||
indent_size = 4
|
||||
end_of_line = lf
|
||||
charset = utf-8
|
||||
trim_trailing_whitespace = true
|
||||
insert_final_newline = true
|
||||
|
||||
[Makefile]
|
||||
indent_style = tab
|
||||
9
.gitea/workflows/check.yml
Normal file
9
.gitea/workflows/check.yml
Normal file
@ -0,0 +1,9 @@
|
||||
name: check
|
||||
on: [push]
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2
|
||||
- name: Build and check
|
||||
run: docker build .
|
||||
21
.gitignore
vendored
Normal file
21
.gitignore
vendored
Normal file
@ -0,0 +1,21 @@
|
||||
# OS
|
||||
.DS_Store
|
||||
Thumbs.db
|
||||
|
||||
# Editors
|
||||
*.swp
|
||||
*.swo
|
||||
*~
|
||||
*.bak
|
||||
.idea/
|
||||
.vscode/
|
||||
*.sublime-*
|
||||
|
||||
# Node
|
||||
node_modules/
|
||||
|
||||
# Environment / secrets
|
||||
.env
|
||||
.env.*
|
||||
*.pem
|
||||
*.key
|
||||
1
.prettierignore
Normal file
1
.prettierignore
Normal file
@ -0,0 +1 @@
|
||||
LICENSE
|
||||
4
.prettierrc
Normal file
4
.prettierrc
Normal file
@ -0,0 +1,4 @@
|
||||
{
|
||||
"proseWrap": "always",
|
||||
"tabWidth": 4
|
||||
}
|
||||
6
Dockerfile
Normal file
6
Dockerfile
Normal file
@ -0,0 +1,6 @@
|
||||
# v22.22.0 2025-05-27
|
||||
FROM node:22-slim@sha256:2f3571cb4deb87a2e2992eaa5ed75d99ad4d348eb7cabe6a62f8f0a3bc9b29c7
|
||||
|
||||
WORKDIR /app
|
||||
COPY . .
|
||||
RUN npm install -g prettier && make check
|
||||
21
LICENSE
Normal file
21
LICENSE
Normal file
@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2026 sneak
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
22
Makefile
Normal file
22
Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
.PHONY: fmt fmt-check lint test check hooks
|
||||
|
||||
fmt:
|
||||
npx prettier --write .
|
||||
|
||||
fmt-check:
|
||||
npx prettier --check .
|
||||
|
||||
lint:
|
||||
@echo "No linter configured for docs-only repo"
|
||||
|
||||
test:
|
||||
@echo "No tests for docs-only repo"
|
||||
|
||||
check: fmt-check
|
||||
@echo "All checks passed"
|
||||
|
||||
hooks:
|
||||
echo '#!/bin/sh\nmake check' > .git/hooks/pre-commit && chmod +x .git/hooks/pre-commit
|
||||
|
||||
docker:
|
||||
docker build .
|
||||
@ -1,7 +1,7 @@
|
||||
# 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
|
||||
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.
|
||||
|
||||
---
|
||||
@ -14,11 +14,11 @@ the big picture so you understand the design decisions.
|
||||
|
||||
### The Starting Point
|
||||
|
||||
OpenClaw gives you a persistent workspace directory and the ability to run
|
||||
tools (shell, web, browser, messaging). Out of the box, the agent wakes up
|
||||
fresh every session with no memory of what happened before. The core challenge
|
||||
is: **how do you turn a stateless LLM into a stateful personal assistant that
|
||||
knows who you are, where you are, what you need, and what it was working on?**
|
||||
OpenClaw gives you a persistent workspace directory and the ability to run tools
|
||||
(shell, web, browser, messaging). Out of the box, the agent wakes up fresh every
|
||||
session with no memory of what happened before. The core challenge is: **how do
|
||||
you turn a stateless LLM into a stateful personal assistant that knows who you
|
||||
are, where you are, what you need, and what it was working on?**
|
||||
|
||||
The answer is files. The workspace IS the agent's brain. Every piece of state,
|
||||
every rule, every memory lives in files that the agent reads on startup and
|
||||
@ -33,12 +33,11 @@ instructions the agent didn't need for most tasks.
|
||||
|
||||
The solution was **factoring out rulesets into focused files:**
|
||||
|
||||
- **AGENTS.md** — the master file. Responsibilities, session startup
|
||||
procedure, high-level rules. Think of it as the table of contents that
|
||||
points to everything else.
|
||||
- **SOUL.md** — personality, tone, values. Separated because it's
|
||||
philosophical, not procedural. Also: it's fun to let the agent evolve this
|
||||
one over time.
|
||||
- **AGENTS.md** — the master file. Responsibilities, session startup procedure,
|
||||
high-level rules. Think of it as the table of contents that points to
|
||||
everything else.
|
||||
- **SOUL.md** — personality, tone, values. Separated because it's philosophical,
|
||||
not procedural. Also: it's fun to let the agent evolve this one over time.
|
||||
- **USER.md** — info about the human. Timezone, communication preferences,
|
||||
basics the agent needs every session.
|
||||
- **MEMORY.md** — curated long-term memory. Only loaded in private sessions
|
||||
@ -83,8 +82,8 @@ on-demand.
|
||||
|
||||
This was probably the single most impactful addition. It's a JSON file
|
||||
(`memory/daily-context.json`) that every session reads on every message. It
|
||||
tracks the current state of the human: where they are, what timezone they're
|
||||
in, whether they're sleeping, when they last took meds, when they last sent a
|
||||
tracks the current state of the human: where they are, what timezone they're in,
|
||||
whether they're sleeping, when they last took meds, when they last sent a
|
||||
message.
|
||||
|
||||
Why JSON instead of markdown? Because it's machine-readable. The agent can
|
||||
@ -92,8 +91,8 @@ update individual fields programmatically, and the structure is unambiguous.
|
||||
Markdown is great for instructions; JSON is great for state.
|
||||
|
||||
The daily context file means:
|
||||
- The agent always knows the human's timezone (critical for a frequent
|
||||
traveler)
|
||||
|
||||
- The agent always knows the human's timezone (critical for a frequent traveler)
|
||||
- Medication reminders fire based on actual timestamps, not guesses
|
||||
- Sleep predictions inform when to send alerts vs stay quiet
|
||||
- Location tracking happens automatically
|
||||
@ -108,13 +107,13 @@ key facts, lessons learned. Think of this as what a human would "just know"
|
||||
about their life.
|
||||
|
||||
During heartbeats, the agent periodically reviews recent daily files and
|
||||
promotes significant items to MEMORY.md, and removes stale info. It's
|
||||
explicitly modeled on how human memory works: raw experience gets processed
|
||||
into lasting knowledge, and irrelevant details fade.
|
||||
promotes significant items to MEMORY.md, and removes stale info. It's explicitly
|
||||
modeled on how human memory works: raw experience gets processed into lasting
|
||||
knowledge, and irrelevant details fade.
|
||||
|
||||
The security model: MEMORY.md is only loaded in private (1:1 DM) sessions.
|
||||
In group chats, the agent works from daily files and daily-context.json only.
|
||||
This prevents personal context from leaking into shared channels.
|
||||
The security model: MEMORY.md is only loaded in private (1:1 DM) sessions. In
|
||||
group chats, the agent works from daily files and daily-context.json only. This
|
||||
prevents personal context from leaking into shared channels.
|
||||
|
||||
### Medication Tracking
|
||||
|
||||
@ -123,18 +122,18 @@ This is a safety-critical system. The design is deliberately paranoid:
|
||||
- **CSV as source of truth.** Not the daily-context boolean, not the agent's
|
||||
memory — the CSV log file is authoritative.
|
||||
- **Double-verification before any action.** The daily context has a
|
||||
`hasTakenDailyMedsToday` boolean AND a `dailyMedsTimestamp`. A midnight
|
||||
cron resets the boolean. But if the human is in a timezone ahead of the
|
||||
server, the reset happens at the wrong time. So the rule is: always verify
|
||||
the timestamp falls on today's date in the human's timezone. The boolean
|
||||
is a convenience hint, never the source of truth.
|
||||
`hasTakenDailyMedsToday` boolean AND a `dailyMedsTimestamp`. A midnight cron
|
||||
resets the boolean. But if the human is in a timezone ahead of the server, the
|
||||
reset happens at the wrong time. So the rule is: always verify the timestamp
|
||||
falls on today's date in the human's timezone. The boolean is a convenience
|
||||
hint, never the source of truth.
|
||||
- **Interval medications anchored to actual doses.** Some meds are "every 5
|
||||
days" or "every 14 days." The next dose date is calculated from the last
|
||||
actual dose timestamp, not from the intended schedule. If a dose is missed,
|
||||
the next date is unknown until the missed dose is taken and logged.
|
||||
- **Overdose prevention.** The agent blocks logging if it detects a same-day
|
||||
duplicate batch. This is the highest-priority safety rule — a duplicate
|
||||
daily batch of certain medications could cause cardiac arrest.
|
||||
duplicate batch. This is the highest-priority safety rule — a duplicate daily
|
||||
batch of certain medications could cause cardiac arrest.
|
||||
- **Escalating alerts.** If daily meds are >26h since last dose, the agent
|
||||
escalates aggressively — ntfy push notification if chat messages go
|
||||
unacknowledged.
|
||||
@ -144,17 +143,18 @@ keeping context costs low for non-medication conversations.
|
||||
|
||||
### Sleep Tracking
|
||||
|
||||
The agent infers sleep from activity gaps rather than requiring explicit
|
||||
"I'm going to sleep" statements. On every message, it checks: was there a
|
||||
gap since the last message that overlaps with the predicted sleep window? If
|
||||
so, log sleep start = last activity before gap, wake = first activity after.
|
||||
The agent infers sleep from activity gaps rather than requiring explicit "I'm
|
||||
going to sleep" statements. On every message, it checks: was there a gap since
|
||||
the last message that overlaps with the predicted sleep window? If so, log sleep
|
||||
start = last activity before gap, wake = first activity after.
|
||||
|
||||
Activity isn't just chat messages — it includes Gitea commits, comments,
|
||||
scheduled flight departures, and any other observable actions.
|
||||
|
||||
Sleep predictions drift over time (the human in this setup tends to sleep
|
||||
~30min later each day), so the agent tracks the trend and extrapolates.
|
||||
Caffeine intake adjusts predictions forward. The predictions feed into:
|
||||
Sleep predictions drift over time (the human in this setup tends to sleep ~30min
|
||||
later each day), so the agent tracks the trend and extrapolates. Caffeine intake
|
||||
adjusts predictions forward. The predictions feed into:
|
||||
|
||||
- When to send alerts vs stay quiet
|
||||
- Sitrep "sleep conflict" warnings (appointment during predicted sleep)
|
||||
- General awareness of the human's schedule
|
||||
@ -162,31 +162,32 @@ Caffeine intake adjusts predictions forward. The predictions feed into:
|
||||
### Location & Timezone Tracking
|
||||
|
||||
The agent always knows where the human is. This matters because:
|
||||
- Times must always be displayed in the human's local timezone, not the
|
||||
server's timezone
|
||||
|
||||
- Times must always be displayed in the human's local timezone, not the server's
|
||||
timezone
|
||||
- "Today" and "tomorrow" mean different things in different timezones
|
||||
- Medication timing needs to account for timezone changes
|
||||
- Flight prep needs local airport info
|
||||
|
||||
The landing checklist (triggered automatically after every flight) updates
|
||||
location, timezone, nearest airport, and lodging in the daily context file.
|
||||
It also checks if any cron jobs have hardcoded timezones that need updating.
|
||||
location, timezone, nearest airport, and lodging in the daily context file. It
|
||||
also checks if any cron jobs have hardcoded timezones that need updating.
|
||||
|
||||
### The Gitea Notification Poller
|
||||
|
||||
OpenClaw has heartbeats, but those are periodic (every ~30min). For Gitea
|
||||
issues and PRs, we wanted near-realtime response. The solution: a tiny Python
|
||||
script that polls the Gitea notifications API every 2 seconds and wakes the
|
||||
agent via OpenClaw's `/hooks/wake` endpoint when new notifications arrive.
|
||||
OpenClaw has heartbeats, but those are periodic (every ~30min). For Gitea issues
|
||||
and PRs, we wanted near-realtime response. The solution: a tiny Python script
|
||||
that polls the Gitea notifications API every 2 seconds and wakes the agent via
|
||||
OpenClaw's `/hooks/wake` endpoint when new notifications arrive.
|
||||
|
||||
Key design decisions:
|
||||
- **The poller never marks notifications as read.** That's the agent's job
|
||||
after it processes them. This prevents the poller and agent from racing.
|
||||
|
||||
- **The poller never marks notifications as read.** That's the agent's job after
|
||||
it processes them. This prevents the poller and agent from racing.
|
||||
- **It tracks notification IDs, not counts.** This way it only fires on
|
||||
genuinely new notifications, not re-reads of existing ones.
|
||||
- **The wake message tells the agent to route output to Gitea/Mattermost,
|
||||
not to DM.** This prevents chatty notification processing from disturbing
|
||||
the human.
|
||||
- **The wake message tells the agent to route output to Gitea/Mattermost, not to
|
||||
DM.** This prevents chatty notification processing from disturbing the human.
|
||||
- **Zero dependencies.** Just Python stdlib (`urllib`, `json`, `time`). Runs
|
||||
anywhere.
|
||||
|
||||
@ -328,30 +329,30 @@ if __name__ == "__main__":
|
||||
main()
|
||||
```
|
||||
|
||||
Run it as a background service (launchd on macOS, systemd on Linux) with the
|
||||
env vars set. It's intentionally simple — no frameworks, no async, no
|
||||
dependencies.
|
||||
Run it as a background service (launchd on macOS, systemd on Linux) with the env
|
||||
vars set. It's intentionally simple — no frameworks, no async, no dependencies.
|
||||
|
||||
### The Daily Diary
|
||||
|
||||
Every day gets a `memory/YYYY-MM-DD.md` file. The agent appends a topic
|
||||
summary to a table after every meaningful conversation:
|
||||
Every day gets a `memory/YYYY-MM-DD.md` file. The agent appends a topic summary
|
||||
to a table after every meaningful conversation:
|
||||
|
||||
```markdown
|
||||
## Topics
|
||||
|
||||
| Time (TZ) | Topic |
|
||||
| ---------- | ------------------------------------------------- |
|
||||
| --------- | ------------------------------------------------ |
|
||||
| 14:30 | Discussed PR review workflow |
|
||||
| 16:00 | Medication logged |
|
||||
| 18:45 | Flight prep blocks created for tomorrow's flight |
|
||||
```
|
||||
|
||||
This serves multiple purposes:
|
||||
|
||||
- Any session can see what's been discussed today without loading full
|
||||
conversation history
|
||||
- The agent can use `sessions_history` to get details on a specific topic
|
||||
if needed
|
||||
- The agent can use `sessions_history` to get details on a specific topic if
|
||||
needed
|
||||
- During memory maintenance, the agent reviews these to decide what's worth
|
||||
promoting to MEMORY.md
|
||||
- It's a simple audit trail of what happened
|
||||
@ -361,8 +362,7 @@ This serves multiple purposes:
|
||||
One of the most important rules: **every single requirement, preference, or
|
||||
instruction the human provides MUST be captured in a file immediately.** Not
|
||||
"mentally noted" — written to disk. Because the agent wakes up fresh every
|
||||
session, a "mental note" is worthless. If it's not in a file, it didn't
|
||||
happen.
|
||||
session, a "mental note" is worthless. If it's not in a file, it didn't happen.
|
||||
|
||||
This applies to everything: project rules ("no mocks in tests"), workflow
|
||||
preferences ("fewer PRs, don't over-split"), corrections, new policies.
|
||||
@ -370,13 +370,14 @@ Immediate write to the daily file, and to MEMORY.md if it's a standing rule.
|
||||
|
||||
### PII-Aware Output Routing
|
||||
|
||||
A lesson learned the hard way: **the audience determines what you can say,
|
||||
not who asked.** If the human asks for a medication status report in a group
|
||||
A lesson learned the hard way: **the audience determines what you can say, not
|
||||
who asked.** If the human asks for a medication status report in a group
|
||||
channel, the agent can't just dump it there — other people can read it. The
|
||||
rule: if the output would contain PII and the channel isn't private, redirect
|
||||
to DM and reply in-channel with "sent privately."
|
||||
rule: if the output would contain PII and the channel isn't private, redirect to
|
||||
DM and reply in-channel with "sent privately."
|
||||
|
||||
This is enforced at multiple levels:
|
||||
|
||||
- AGENTS.md has a warning banner at the top
|
||||
- The checklist system catches it before action
|
||||
- Channel-specific rule files (like our `memory/JAMES_CHAT.md`) define what's
|
||||
@ -386,28 +387,29 @@ This is enforced at multiple levels:
|
||||
|
||||
When spawning coding sub-agents for PR work, each one MUST clone to a fresh
|
||||
temporary directory. Never share git clones between agents — dirty working
|
||||
directories cause false CI results, merge conflicts, and wrong file state.
|
||||
The rule: `cd $(mktemp -d) && git clone <url> . && ...`
|
||||
directories cause false CI results, merge conflicts, and wrong file state. The
|
||||
rule: `cd $(mktemp -d) && git clone <url> . && ...`
|
||||
|
||||
### The Heartbeat System
|
||||
|
||||
OpenClaw polls the agent periodically with a configurable prompt. The agent
|
||||
reads HEARTBEAT.md and decides what to do. We keep HEARTBEAT.md small
|
||||
(focused checklist) to minimize token burn on these frequent checks.
|
||||
reads HEARTBEAT.md and decides what to do. We keep HEARTBEAT.md small (focused
|
||||
checklist) to minimize token burn on these frequent checks.
|
||||
|
||||
The heartbeat handles:
|
||||
|
||||
- Gitea inbox triage (check for new assignments)
|
||||
- Flight prep block creation (look ahead 7 days)
|
||||
- Open project review (can I take a step on anything?)
|
||||
- Workspace sync (commit and push changes)
|
||||
- Periodic memory maintenance
|
||||
|
||||
State tracking in `memory/heartbeat-state.json` prevents redundant checks
|
||||
(e.g., don't re-check email if you checked 10 minutes ago).
|
||||
State tracking in `memory/heartbeat-state.json` prevents redundant checks (e.g.,
|
||||
don't re-check email if you checked 10 minutes ago).
|
||||
|
||||
The key output rule: heartbeats should either be `HEARTBEAT_OK` (nothing to
|
||||
do) or a direct alert. Work narration goes to a designated status channel,
|
||||
never to the human's DM.
|
||||
The key output rule: heartbeats should either be `HEARTBEAT_OK` (nothing to do)
|
||||
or a direct alert. Work narration goes to a designated status channel, never to
|
||||
the human's DM.
|
||||
|
||||
### Putting It All Together
|
||||
|
||||
@ -417,8 +419,8 @@ The system works as a loop:
|
||||
2. **Message arrives** → check daily-context for state changes (sleep gap?
|
||||
location change? meds overdue?), respond to the message, update state
|
||||
3. **Heartbeat fires** → check inbox, projects, flights, sync workspace
|
||||
4. **External event** (Gitea poller wake) → process notification, respond
|
||||
via appropriate channel
|
||||
4. **External event** (Gitea poller wake) → process notification, respond via
|
||||
appropriate channel
|
||||
5. **Session ends** → state persists in files for next session
|
||||
|
||||
The files are the continuity. The agent is stateless; the workspace is not.
|
||||
@ -481,7 +483,8 @@ 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)
|
||||
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`
|
||||
|
||||
@ -533,6 +536,7 @@ 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
|
||||
@ -555,33 +559,32 @@ dynamically** based on what it thinks you should know.
|
||||
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.
|
||||
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.
|
||||
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
|
||||
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
|
||||
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.**
|
||||
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.
|
||||
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:
|
||||
@ -600,8 +603,8 @@ needs to act on.
|
||||
### Time display tip:
|
||||
|
||||
```markdown
|
||||
Include current time in local timezone, UTC, and any other relevant timezone
|
||||
at the top.
|
||||
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.
|
||||
@ -626,17 +629,17 @@ Date,SleepTime,WakeTime,TimeZone,Duration,Status,Notes
|
||||
```markdown
|
||||
### Sleep Tracking
|
||||
|
||||
- **`memory/sleep-log.csv`** — columns: Date, SleepTime, WakeTime,
|
||||
TimeZone, Duration, Status, Notes
|
||||
- **`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.
|
||||
- **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:
|
||||
@ -702,6 +705,7 @@ Date,City,Country,Timezone
|
||||
|
||||
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
|
||||
@ -742,14 +746,14 @@ Date,Time,TimeZone,Medication,Dosage
|
||||
|
||||
- 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
|
||||
- "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.
|
||||
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.**
|
||||
@ -762,7 +766,7 @@ dailyMedsTimestamp.**
|
||||
**Ideal dosing window:** every 24h ±4h. Hard minimum: 14h between doses.
|
||||
|
||||
| Medication | Dosage |
|
||||
| ------------ | ------ |
|
||||
| ----------- | ------ |
|
||||
| (your meds) | (dose) |
|
||||
|
||||
## Interval-Based Medications
|
||||
@ -774,6 +778,7 @@ Scheduling anchored to last actual dose, NOT intended dates.
|
||||
| (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
|
||||
@ -812,20 +817,20 @@ Scheduling anchored to last actual dose, NOT intended dates.
|
||||
### 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").
|
||||
**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.
|
||||
`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.
|
||||
|
||||
---
|
||||
|
||||
@ -851,8 +856,8 @@ Date,FlightNumber,Origin,Destination,Duration,Alliance
|
||||
```markdown
|
||||
## Flight Prep Blocks (daily)
|
||||
|
||||
Run `khal list today 7d`. For flights missing "shower and dress" /
|
||||
"travel to airport" blocks, create them:
|
||||
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
|
||||
@ -928,7 +933,7 @@ completed. Every session can read these.
|
||||
## Topics
|
||||
|
||||
| Time | Topic | Session |
|
||||
|------|-------|---------|
|
||||
| ----- | ---------------------------- | ------- |
|
||||
| 14:30 | Discussed PR review workflow | main |
|
||||
| 16:00 | Medication logged | main |
|
||||
|
||||
@ -993,15 +998,19 @@ stay quiet.
|
||||
# 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
|
||||
@ -1013,6 +1022,7 @@ stay quiet.
|
||||
## 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
|
||||
@ -1036,12 +1046,14 @@ Never send internal thinking or status narration to user's DM. Output should be:
|
||||
|
||||
```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
|
||||
@ -1068,8 +1080,8 @@ Find issues/PRs assigned to me or where I'm @-mentioned → do the work.
|
||||
- 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.
|
||||
Workflow: issue → branch → PR "(closes #X)" → review/rework → assign user when
|
||||
all checks pass + reviewed.
|
||||
|
||||
### Rules
|
||||
|
||||
@ -1082,10 +1094,10 @@ when all checks pass + reviewed.
|
||||
|
||||
### 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).
|
||||
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).
|
||||
|
||||
---
|
||||
|
||||
@ -1099,8 +1111,7 @@ For complex coding tasks, spawn isolated sub-agents.
|
||||
### 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`)
|
||||
- Each sub-agent MUST clone to a unique temporary directory (e.g. `mktemp -d`)
|
||||
- When spawning, always instruct: `cd $(mktemp -d) && git clone <url> . && ...`
|
||||
- Dirty working directories cause false CI results
|
||||
|
||||
@ -1146,12 +1157,14 @@ Rules for when the agent is in group chats with multiple people:
|
||||
### 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"
|
||||
@ -1163,6 +1176,7 @@ 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 → 🤔, 💡
|
||||
@ -1180,12 +1194,12 @@ 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
|
||||
- **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.
|
||||
```
|
||||
|
||||
@ -1193,9 +1207,9 @@ Never lose a rule or preference your human states:
|
||||
|
||||
## 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.
|
||||
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:
|
||||
|
||||
@ -1213,26 +1227,29 @@ group channel, you can't just dump it there — other people can read it.
|
||||
|
||||
### 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.
|
||||
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.
|
||||
|
||||
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:
|
||||
|
||||
@ -1250,6 +1267,7 @@ history and recovery:
|
||||
## 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
|
||||
@ -1262,9 +1280,9 @@ No apologies. No promises. Fix the system.
|
||||
```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.
|
||||
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.
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
14
README.md
14
README.md
@ -11,8 +11,8 @@ agent) under the direction of [@sneak](https://sneak.berlin).
|
||||
for OpenClaw agents: workspace bootstrapping, daily context state files,
|
||||
sitrep (situation report) prompts, sleep tracking, medication tracking,
|
||||
timezone-aware location tracking, flight/travel logging, memory architecture,
|
||||
heartbeat configuration, Gitea integration, sub-agent management, and
|
||||
security patterns.
|
||||
heartbeat configuration, Gitea integration, sub-agent management, and security
|
||||
patterns.
|
||||
|
||||
## Purpose
|
||||
|
||||
@ -43,11 +43,11 @@ This repository is **public to the entire internet.** The publishing agent
|
||||
- **Credentials:** API keys, tokens, passwords, SSH keys, webhook URLs with
|
||||
secrets, ntfy topic IDs
|
||||
- **Actual log data:** medication logs, sleep logs, flight logs, location logs,
|
||||
daily memory files — only the *format/schema* is shared, never the data
|
||||
daily memory files — only the _format/schema_ is shared, never the data
|
||||
- **Infrastructure details:** specific hostnames, IP addresses, Tailscale/VPN
|
||||
configurations, server names
|
||||
- **Private repository contents:** code from private repos, issue contents,
|
||||
PR discussions
|
||||
- **Private repository contents:** code from private repos, issue contents, PR
|
||||
discussions
|
||||
- **Financial information:** account numbers, transaction details
|
||||
|
||||
### Pre-Publish Checklist
|
||||
@ -56,8 +56,8 @@ Before every commit to this repo, the agent:
|
||||
|
||||
1. Scans the diff for PII patterns (names, emails, addresses, phone numbers,
|
||||
coordinates, hostnames, API keys, tokens)
|
||||
2. Verifies all examples use placeholder values (`YOUR-TOPIC-ID`,
|
||||
`example.com`, `(your meds)`, etc.)
|
||||
2. Verifies all examples use placeholder values (`YOUR-TOPIC-ID`, `example.com`,
|
||||
`(your meds)`, etc.)
|
||||
3. Confirms no real log data is included — only format specifications
|
||||
4. Reviews for infrastructure leaks (internal hostnames, IP ranges, VPN details)
|
||||
5. Gets explicit approval from the repo owner for new document types
|
||||
|
||||
Loading…
Reference in New Issue
Block a user