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
|
# OPENCLAW_TRICKS.md — Configuration Recipes for OpenClaw Agents
|
||||||
|
|
||||||
A collection of tested patterns, prompts, and file structures for configuring
|
A collection of tested patterns, prompts, and file structures for configuring an
|
||||||
an OpenClaw agent as a proactive personal assistant. These are extracted from a
|
OpenClaw agent as a proactive personal assistant. These are extracted from a
|
||||||
production setup that's been running since early 2026.
|
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
|
### The Starting Point
|
||||||
|
|
||||||
OpenClaw gives you a persistent workspace directory and the ability to run
|
OpenClaw gives you a persistent workspace directory and the ability to run tools
|
||||||
tools (shell, web, browser, messaging). Out of the box, the agent wakes up
|
(shell, web, browser, messaging). Out of the box, the agent wakes up fresh every
|
||||||
fresh every session with no memory of what happened before. The core challenge
|
session with no memory of what happened before. The core challenge is: **how do
|
||||||
is: **how do you turn a stateless LLM into a stateful personal assistant that
|
you turn a stateless LLM into a stateful personal assistant that knows who you
|
||||||
knows who you are, where you are, what you need, and what it was working on?**
|
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,
|
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
|
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:**
|
The solution was **factoring out rulesets into focused files:**
|
||||||
|
|
||||||
- **AGENTS.md** — the master file. Responsibilities, session startup
|
- **AGENTS.md** — the master file. Responsibilities, session startup procedure,
|
||||||
procedure, high-level rules. Think of it as the table of contents that
|
high-level rules. Think of it as the table of contents that points to
|
||||||
points to everything else.
|
everything else.
|
||||||
- **SOUL.md** — personality, tone, values. Separated because it's
|
- **SOUL.md** — personality, tone, values. Separated because it's philosophical,
|
||||||
philosophical, not procedural. Also: it's fun to let the agent evolve this
|
not procedural. Also: it's fun to let the agent evolve this one over time.
|
||||||
one over time.
|
|
||||||
- **USER.md** — info about the human. Timezone, communication preferences,
|
- **USER.md** — info about the human. Timezone, communication preferences,
|
||||||
basics the agent needs every session.
|
basics the agent needs every session.
|
||||||
- **MEMORY.md** — curated long-term memory. Only loaded in private sessions
|
- **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
|
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
|
(`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
|
tracks the current state of the human: where they are, what timezone they're in,
|
||||||
in, whether they're sleeping, when they last took meds, when they last sent a
|
whether they're sleeping, when they last took meds, when they last sent a
|
||||||
message.
|
message.
|
||||||
|
|
||||||
Why JSON instead of markdown? Because it's machine-readable. The agent can
|
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.
|
Markdown is great for instructions; JSON is great for state.
|
||||||
|
|
||||||
The daily context file means:
|
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
|
- Medication reminders fire based on actual timestamps, not guesses
|
||||||
- Sleep predictions inform when to send alerts vs stay quiet
|
- Sleep predictions inform when to send alerts vs stay quiet
|
||||||
- Location tracking happens automatically
|
- 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.
|
about their life.
|
||||||
|
|
||||||
During heartbeats, the agent periodically reviews recent daily files and
|
During heartbeats, the agent periodically reviews recent daily files and
|
||||||
promotes significant items to MEMORY.md, and removes stale info. It's
|
promotes significant items to MEMORY.md, and removes stale info. It's explicitly
|
||||||
explicitly modeled on how human memory works: raw experience gets processed
|
modeled on how human memory works: raw experience gets processed into lasting
|
||||||
into lasting knowledge, and irrelevant details fade.
|
knowledge, and irrelevant details fade.
|
||||||
|
|
||||||
The security model: MEMORY.md is only loaded in private (1:1 DM) sessions.
|
The security model: MEMORY.md is only loaded in private (1:1 DM) sessions. In
|
||||||
In group chats, the agent works from daily files and daily-context.json only.
|
group chats, the agent works from daily files and daily-context.json only. This
|
||||||
This prevents personal context from leaking into shared channels.
|
prevents personal context from leaking into shared channels.
|
||||||
|
|
||||||
### Medication Tracking
|
### 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
|
- **CSV as source of truth.** Not the daily-context boolean, not the agent's
|
||||||
memory — the CSV log file is authoritative.
|
memory — the CSV log file is authoritative.
|
||||||
- **Double-verification before any action.** The daily context has a
|
- **Double-verification before any action.** The daily context has a
|
||||||
`hasTakenDailyMedsToday` boolean AND a `dailyMedsTimestamp`. A midnight
|
`hasTakenDailyMedsToday` boolean AND a `dailyMedsTimestamp`. A midnight cron
|
||||||
cron resets the boolean. But if the human is in a timezone ahead of the
|
resets the boolean. But if the human is in a timezone ahead of the server, the
|
||||||
server, the reset happens at the wrong time. So the rule is: always verify
|
reset happens at the wrong time. So the rule is: always verify the timestamp
|
||||||
the timestamp falls on today's date in the human's timezone. The boolean
|
falls on today's date in the human's timezone. The boolean is a convenience
|
||||||
is a convenience hint, never the source of truth.
|
hint, never the source of truth.
|
||||||
- **Interval medications anchored to actual doses.** Some meds are "every 5
|
- **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
|
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,
|
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.
|
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
|
- **Overdose prevention.** The agent blocks logging if it detects a same-day
|
||||||
duplicate batch. This is the highest-priority safety rule — a duplicate
|
duplicate batch. This is the highest-priority safety rule — a duplicate daily
|
||||||
daily batch of certain medications could cause cardiac arrest.
|
batch of certain medications could cause cardiac arrest.
|
||||||
- **Escalating alerts.** If daily meds are >26h since last dose, the agent
|
- **Escalating alerts.** If daily meds are >26h since last dose, the agent
|
||||||
escalates aggressively — ntfy push notification if chat messages go
|
escalates aggressively — ntfy push notification if chat messages go
|
||||||
unacknowledged.
|
unacknowledged.
|
||||||
@ -144,17 +143,18 @@ keeping context costs low for non-medication conversations.
|
|||||||
|
|
||||||
### Sleep Tracking
|
### Sleep Tracking
|
||||||
|
|
||||||
The agent infers sleep from activity gaps rather than requiring explicit
|
The agent infers sleep from activity gaps rather than requiring explicit "I'm
|
||||||
"I'm going to sleep" statements. On every message, it checks: was there a
|
going to sleep" statements. On every message, it checks: was there a gap since
|
||||||
gap since the last message that overlaps with the predicted sleep window? If
|
the last message that overlaps with the predicted sleep window? If so, log sleep
|
||||||
so, log sleep start = last activity before gap, wake = first activity after.
|
start = last activity before gap, wake = first activity after.
|
||||||
|
|
||||||
Activity isn't just chat messages — it includes Gitea commits, comments,
|
Activity isn't just chat messages — it includes Gitea commits, comments,
|
||||||
scheduled flight departures, and any other observable actions.
|
scheduled flight departures, and any other observable actions.
|
||||||
|
|
||||||
Sleep predictions drift over time (the human in this setup tends to sleep
|
Sleep predictions drift over time (the human in this setup tends to sleep ~30min
|
||||||
~30min later each day), so the agent tracks the trend and extrapolates.
|
later each day), so the agent tracks the trend and extrapolates. Caffeine intake
|
||||||
Caffeine intake adjusts predictions forward. The predictions feed into:
|
adjusts predictions forward. The predictions feed into:
|
||||||
|
|
||||||
- When to send alerts vs stay quiet
|
- When to send alerts vs stay quiet
|
||||||
- Sitrep "sleep conflict" warnings (appointment during predicted sleep)
|
- Sitrep "sleep conflict" warnings (appointment during predicted sleep)
|
||||||
- General awareness of the human's schedule
|
- General awareness of the human's schedule
|
||||||
@ -162,31 +162,32 @@ Caffeine intake adjusts predictions forward. The predictions feed into:
|
|||||||
### Location & Timezone Tracking
|
### Location & Timezone Tracking
|
||||||
|
|
||||||
The agent always knows where the human is. This matters because:
|
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
|
- "Today" and "tomorrow" mean different things in different timezones
|
||||||
- Medication timing needs to account for timezone changes
|
- Medication timing needs to account for timezone changes
|
||||||
- Flight prep needs local airport info
|
- Flight prep needs local airport info
|
||||||
|
|
||||||
The landing checklist (triggered automatically after every flight) updates
|
The landing checklist (triggered automatically after every flight) updates
|
||||||
location, timezone, nearest airport, and lodging in the daily context file.
|
location, timezone, nearest airport, and lodging in the daily context file. It
|
||||||
It also checks if any cron jobs have hardcoded timezones that need updating.
|
also checks if any cron jobs have hardcoded timezones that need updating.
|
||||||
|
|
||||||
### The Gitea Notification Poller
|
### The Gitea Notification Poller
|
||||||
|
|
||||||
OpenClaw has heartbeats, but those are periodic (every ~30min). For Gitea
|
OpenClaw has heartbeats, but those are periodic (every ~30min). For Gitea issues
|
||||||
issues and PRs, we wanted near-realtime response. The solution: a tiny Python
|
and PRs, we wanted near-realtime response. The solution: a tiny Python script
|
||||||
script that polls the Gitea notifications API every 2 seconds and wakes the
|
that polls the Gitea notifications API every 2 seconds and wakes the agent via
|
||||||
agent via OpenClaw's `/hooks/wake` endpoint when new notifications arrive.
|
OpenClaw's `/hooks/wake` endpoint when new notifications arrive.
|
||||||
|
|
||||||
Key design decisions:
|
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
|
- **It tracks notification IDs, not counts.** This way it only fires on
|
||||||
genuinely new notifications, not re-reads of existing ones.
|
genuinely new notifications, not re-reads of existing ones.
|
||||||
- **The wake message tells the agent to route output to Gitea/Mattermost,
|
- **The wake message tells the agent to route output to Gitea/Mattermost, not to
|
||||||
not to DM.** This prevents chatty notification processing from disturbing
|
DM.** This prevents chatty notification processing from disturbing the human.
|
||||||
the human.
|
|
||||||
- **Zero dependencies.** Just Python stdlib (`urllib`, `json`, `time`). Runs
|
- **Zero dependencies.** Just Python stdlib (`urllib`, `json`, `time`). Runs
|
||||||
anywhere.
|
anywhere.
|
||||||
|
|
||||||
@ -328,30 +329,30 @@ if __name__ == "__main__":
|
|||||||
main()
|
main()
|
||||||
```
|
```
|
||||||
|
|
||||||
Run it as a background service (launchd on macOS, systemd on Linux) with the
|
Run it as a background service (launchd on macOS, systemd on Linux) with the env
|
||||||
env vars set. It's intentionally simple — no frameworks, no async, no
|
vars set. It's intentionally simple — no frameworks, no async, no dependencies.
|
||||||
dependencies.
|
|
||||||
|
|
||||||
### The Daily Diary
|
### The Daily Diary
|
||||||
|
|
||||||
Every day gets a `memory/YYYY-MM-DD.md` file. The agent appends a topic
|
Every day gets a `memory/YYYY-MM-DD.md` file. The agent appends a topic summary
|
||||||
summary to a table after every meaningful conversation:
|
to a table after every meaningful conversation:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
## Topics
|
## Topics
|
||||||
|
|
||||||
| Time (TZ) | Topic |
|
| Time (TZ) | Topic |
|
||||||
| ---------- | ------------------------------------------------- |
|
| --------- | ------------------------------------------------ |
|
||||||
| 14:30 | Discussed PR review workflow |
|
| 14:30 | Discussed PR review workflow |
|
||||||
| 16:00 | Medication logged |
|
| 16:00 | Medication logged |
|
||||||
| 18:45 | Flight prep blocks created for tomorrow's flight |
|
| 18:45 | Flight prep blocks created for tomorrow's flight |
|
||||||
```
|
```
|
||||||
|
|
||||||
This serves multiple purposes:
|
This serves multiple purposes:
|
||||||
|
|
||||||
- Any session can see what's been discussed today without loading full
|
- Any session can see what's been discussed today without loading full
|
||||||
conversation history
|
conversation history
|
||||||
- The agent can use `sessions_history` to get details on a specific topic
|
- The agent can use `sessions_history` to get details on a specific topic if
|
||||||
if needed
|
needed
|
||||||
- During memory maintenance, the agent reviews these to decide what's worth
|
- During memory maintenance, the agent reviews these to decide what's worth
|
||||||
promoting to MEMORY.md
|
promoting to MEMORY.md
|
||||||
- It's a simple audit trail of what happened
|
- 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
|
One of the most important rules: **every single requirement, preference, or
|
||||||
instruction the human provides MUST be captured in a file immediately.** Not
|
instruction the human provides MUST be captured in a file immediately.** Not
|
||||||
"mentally noted" — written to disk. Because the agent wakes up fresh every
|
"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
|
session, a "mental note" is worthless. If it's not in a file, it didn't happen.
|
||||||
happen.
|
|
||||||
|
|
||||||
This applies to everything: project rules ("no mocks in tests"), workflow
|
This applies to everything: project rules ("no mocks in tests"), workflow
|
||||||
preferences ("fewer PRs, don't over-split"), corrections, new policies.
|
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
|
### PII-Aware Output Routing
|
||||||
|
|
||||||
A lesson learned the hard way: **the audience determines what you can say,
|
A lesson learned the hard way: **the audience determines what you can say, not
|
||||||
not who asked.** If the human asks for a medication status report in a group
|
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
|
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
|
rule: if the output would contain PII and the channel isn't private, redirect to
|
||||||
to DM and reply in-channel with "sent privately."
|
DM and reply in-channel with "sent privately."
|
||||||
|
|
||||||
This is enforced at multiple levels:
|
This is enforced at multiple levels:
|
||||||
|
|
||||||
- AGENTS.md has a warning banner at the top
|
- AGENTS.md has a warning banner at the top
|
||||||
- The checklist system catches it before action
|
- The checklist system catches it before action
|
||||||
- Channel-specific rule files (like our `memory/JAMES_CHAT.md`) define what's
|
- 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
|
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
|
temporary directory. Never share git clones between agents — dirty working
|
||||||
directories cause false CI results, merge conflicts, and wrong file state.
|
directories cause false CI results, merge conflicts, and wrong file state. The
|
||||||
The rule: `cd $(mktemp -d) && git clone <url> . && ...`
|
rule: `cd $(mktemp -d) && git clone <url> . && ...`
|
||||||
|
|
||||||
### The Heartbeat System
|
### The Heartbeat System
|
||||||
|
|
||||||
OpenClaw polls the agent periodically with a configurable prompt. The agent
|
OpenClaw polls the agent periodically with a configurable prompt. The agent
|
||||||
reads HEARTBEAT.md and decides what to do. We keep HEARTBEAT.md small
|
reads HEARTBEAT.md and decides what to do. We keep HEARTBEAT.md small (focused
|
||||||
(focused checklist) to minimize token burn on these frequent checks.
|
checklist) to minimize token burn on these frequent checks.
|
||||||
|
|
||||||
The heartbeat handles:
|
The heartbeat handles:
|
||||||
|
|
||||||
- Gitea inbox triage (check for new assignments)
|
- Gitea inbox triage (check for new assignments)
|
||||||
- Flight prep block creation (look ahead 7 days)
|
- Flight prep block creation (look ahead 7 days)
|
||||||
- Open project review (can I take a step on anything?)
|
- Open project review (can I take a step on anything?)
|
||||||
- Workspace sync (commit and push changes)
|
- Workspace sync (commit and push changes)
|
||||||
- Periodic memory maintenance
|
- Periodic memory maintenance
|
||||||
|
|
||||||
State tracking in `memory/heartbeat-state.json` prevents redundant checks
|
State tracking in `memory/heartbeat-state.json` prevents redundant checks (e.g.,
|
||||||
(e.g., don't re-check email if you checked 10 minutes ago).
|
don't re-check email if you checked 10 minutes ago).
|
||||||
|
|
||||||
The key output rule: heartbeats should either be `HEARTBEAT_OK` (nothing to
|
The key output rule: heartbeats should either be `HEARTBEAT_OK` (nothing to do)
|
||||||
do) or a direct alert. Work narration goes to a designated status channel,
|
or a direct alert. Work narration goes to a designated status channel, never to
|
||||||
never to the human's DM.
|
the human's DM.
|
||||||
|
|
||||||
### Putting It All Together
|
### 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?
|
2. **Message arrives** → check daily-context for state changes (sleep gap?
|
||||||
location change? meds overdue?), respond to the message, update state
|
location change? meds overdue?), respond to the message, update state
|
||||||
3. **Heartbeat fires** → check inbox, projects, flights, sync workspace
|
3. **Heartbeat fires** → check inbox, projects, flights, sync workspace
|
||||||
4. **External event** (Gitea poller wake) → process notification, respond
|
4. **External event** (Gitea poller wake) → process notification, respond via
|
||||||
via appropriate channel
|
appropriate channel
|
||||||
5. **Session ends** → state persists in files for next session
|
5. **Session ends** → state persists in files for next session
|
||||||
|
|
||||||
The files are the continuity. The agent is stateless; the workspace is not.
|
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
|
1. Read `SOUL.md` — this is who you are
|
||||||
2. Read `USER.md` — this is who you're helping
|
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
|
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`
|
5. **If in MAIN SESSION** (direct chat with your human): Also read `MEMORY.md`
|
||||||
|
|
||||||
@ -502,23 +505,23 @@ reads on every message. It tracks the current state of your human.
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"isSleeping": false,
|
"isSleeping": false,
|
||||||
"lastKnownWakeTime": "2026-02-28T12:30:00+07:00",
|
"lastKnownWakeTime": "2026-02-28T12:30:00+07:00",
|
||||||
"predictedSleepTime": "2026-03-01T05:30:00+07:00",
|
"predictedSleepTime": "2026-03-01T05:30:00+07:00",
|
||||||
"predictedWakeTime": "2026-03-01T12:45:00+07:00",
|
"predictedWakeTime": "2026-03-01T12:45:00+07:00",
|
||||||
"hasTakenDailyMedsToday": false,
|
"hasTakenDailyMedsToday": false,
|
||||||
"dailyMedsTimestamp": "2026-02-27T11:43:00+07:00",
|
"dailyMedsTimestamp": "2026-02-27T11:43:00+07:00",
|
||||||
"lastCaffeineTimestamp": null,
|
"lastCaffeineTimestamp": null,
|
||||||
"currentLocation": "City (IATA)",
|
"currentLocation": "City (IATA)",
|
||||||
"currentTimezone": "Asia/Bangkok",
|
"currentTimezone": "Asia/Bangkok",
|
||||||
"currentLodging": "Hotel Name",
|
"currentLodging": "Hotel Name",
|
||||||
"travelLeg": "Description of current travel phase",
|
"travelLeg": "Description of current travel phase",
|
||||||
"nearestAirport": "ICAO code",
|
"nearestAirport": "ICAO code",
|
||||||
"lastMessageFromUser": "2026-02-28T05:20:00+07:00",
|
"lastMessageFromUser": "2026-02-28T05:20:00+07:00",
|
||||||
"lastMessageChannel": "mattermost",
|
"lastMessageChannel": "mattermost",
|
||||||
"isAvailable": true,
|
"isAvailable": true,
|
||||||
"lastUpdated": "2026-02-28T06:00:00+07:00",
|
"lastUpdated": "2026-02-28T06:00:00+07:00",
|
||||||
"lastSleep": "actual: 2026-02-28 05:15-12:30 ICT (~7h15m). Stable pattern."
|
"lastSleep": "actual: 2026-02-28 05:15-12:30 ICT (~7h15m). Stable pattern."
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -533,6 +536,7 @@ directly.
|
|||||||
```
|
```
|
||||||
|
|
||||||
### Why it works:
|
### Why it works:
|
||||||
|
|
||||||
- Every session reads this first, so the agent always knows where you are
|
- 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
|
- Sleep predictions help the agent decide when to alert vs stay quiet
|
||||||
- Medication timestamps enable overdue detection
|
- 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:
|
When the user says "sitrep", provide a concise summary covering:
|
||||||
|
|
||||||
1. **Daily meds** — taken today or not
|
1. **Daily meds** — taken today or not
|
||||||
2. **Interval meds** — any due/overdue or upcoming in next 48h.
|
2. **Interval meds** — any due/overdue or upcoming in next 48h. ALWAYS include
|
||||||
ALWAYS include "X days from now" countdown. ALWAYS include day of week.
|
"X days from now" countdown. ALWAYS include day of week.
|
||||||
3. **Open issues assigned to me** — count
|
3. **Open issues assigned to me** — count
|
||||||
4. **Open issues assigned to user** — count + brief summary
|
4. **Open issues assigned to user** — count + brief summary
|
||||||
5. **Upcoming travel** — flights in next 72h with times/airports.
|
5. **Upcoming travel** — flights in next 72h with times/airports. ALWAYS also
|
||||||
ALWAYS also include the next known flight even if beyond 72h.
|
include the next known flight even if beyond 72h.
|
||||||
6. **Upcoming appointments** — next 48h
|
6. **Upcoming appointments** — next 48h
|
||||||
7. **Todo list** — overdue, due today, due tomorrow (separate categories)
|
7. **Todo list** — overdue, due today, due tomorrow (separate categories)
|
||||||
8. **Unbooked travel** — flights that need booking. Flag deadlines.
|
8. **Unbooked travel** — flights that need booking. Flag deadlines.
|
||||||
9. **Sleep conflicts** — appointments in next 48h that fall within
|
9. **Sleep conflicts** — appointments in next 48h that fall within predicted
|
||||||
predicted sleep window
|
sleep window
|
||||||
10. **Sleep** — one-line summary of last sleep + drift trend + concerns
|
10. **Sleep** — one-line summary of last sleep + drift trend + concerns
|
||||||
11. **Unanswered questions** — questions the agent asked that haven't
|
11. **Unanswered questions** — questions the agent asked that haven't been
|
||||||
been answered
|
answered
|
||||||
12. **Weather alerts** — only if significant or extreme. Use METAR from
|
12. **Weather alerts** — only if significant or extreme. Use METAR from
|
||||||
aviationweather.gov. Omit if nothing notable.
|
aviationweather.gov. Omit if nothing notable.
|
||||||
13. **Overdue reminders** — anything pending
|
13. **Overdue reminders** — anything pending
|
||||||
14. **Open projects** — one-line status per project
|
14. **Open projects** — one-line status per project
|
||||||
|
|
||||||
Before generating a sitrep, review the last 3 days of daily memory files
|
Before generating a sitrep, review the last 3 days of daily memory files for
|
||||||
for context. **If anything notable isn't covered by the items above —
|
context. **If anything notable isn't covered by the items above — recent
|
||||||
recent lessons, pending decisions, things you think the user should know
|
lessons, pending decisions, things you think the user should know about — add
|
||||||
about — add additional sections as needed.**
|
additional sections as needed.**
|
||||||
|
|
||||||
Omit any item that is "none" or zero. Keep it scannable. Use bullet
|
Omit any item that is "none" or zero. Keep it scannable. Use bullet points, not
|
||||||
points, not prose. Only surface things the user might not know about or
|
prose. Only surface things the user might not know about or needs to act on.
|
||||||
needs to act on.
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Key design decisions:
|
### Key design decisions:
|
||||||
@ -600,8 +603,8 @@ needs to act on.
|
|||||||
### Time display tip:
|
### Time display tip:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
Include current time in local timezone, UTC, and any other relevant timezone
|
Include current time in local timezone, UTC, and any other relevant timezone at
|
||||||
at the top.
|
the top.
|
||||||
```
|
```
|
||||||
|
|
||||||
This anchors the reader and makes all the relative times unambiguous.
|
This anchors the reader and makes all the relative times unambiguous.
|
||||||
@ -626,28 +629,28 @@ Date,SleepTime,WakeTime,TimeZone,Duration,Status,Notes
|
|||||||
```markdown
|
```markdown
|
||||||
### Sleep Tracking
|
### Sleep Tracking
|
||||||
|
|
||||||
- **`memory/sleep-log.csv`** — columns: Date, SleepTime, WakeTime,
|
- **`memory/sleep-log.csv`** — columns: Date, SleepTime, WakeTime, TimeZone,
|
||||||
TimeZone, Duration, Status, Notes
|
Duration, Status, Notes
|
||||||
- Infer sleep/wake times from message activity and explicit statements
|
- Infer sleep/wake times from message activity and explicit statements
|
||||||
- User's sleep pattern drifts later each day; typical duration 4–8 hours
|
- User's sleep pattern drifts later each day; typical duration 4–8 hours
|
||||||
- Update daily-context.json isSleeping field accordingly
|
- Update daily-context.json isSleeping field accordingly
|
||||||
- **On every message from user:** if there was a communication gap
|
- **On every message from user:** if there was a communication gap overlapping
|
||||||
overlapping predicted sleep time, infer a sleep window (sleep start =
|
predicted sleep time, infer a sleep window (sleep start = last activity before
|
||||||
last activity before gap, wake = first activity after gap). Activity
|
gap, wake = first activity after gap). Activity includes direct messages, git
|
||||||
includes direct messages, git commits/comments, scheduled flight
|
commits/comments, scheduled flight departures, and any other observable
|
||||||
departures, and any other observable actions — not just chat messages.
|
actions — not just chat messages. Log based on observed gaps only, never from
|
||||||
Log based on observed gaps only, never from mathematical predictions.
|
mathematical predictions.
|
||||||
```
|
```
|
||||||
|
|
||||||
### Daily context fields for sleep:
|
### Daily context fields for sleep:
|
||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"isSleeping": false,
|
"isSleeping": false,
|
||||||
"lastKnownWakeTime": "2026-02-28T12:30:00+07:00",
|
"lastKnownWakeTime": "2026-02-28T12:30:00+07:00",
|
||||||
"predictedSleepTime": "2026-03-01T05:30:00+07:00",
|
"predictedSleepTime": "2026-03-01T05:30:00+07:00",
|
||||||
"predictedWakeTime": "2026-03-01T12:45:00+07:00",
|
"predictedWakeTime": "2026-03-01T12:45:00+07:00",
|
||||||
"lastSleep": "actual: 2026-02-28 05:15-12:30 ICT (~7h15m). Stable pattern."
|
"lastSleep": "actual: 2026-02-28 05:15-12:30 ICT (~7h15m). Stable pattern."
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -665,7 +668,7 @@ uses predictions to:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"lastCaffeineTimestamp": "2026-02-10T00:45:00-08:00"
|
"lastCaffeineTimestamp": "2026-02-10T00:45:00-08:00"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -702,6 +705,7 @@ Date,City,Country,Timezone
|
|||||||
|
|
||||||
OpenClaw runs on a server (probably in a fixed timezone). Your human travels.
|
OpenClaw runs on a server (probably in a fixed timezone). Your human travels.
|
||||||
Without explicit timezone tracking:
|
Without explicit timezone tracking:
|
||||||
|
|
||||||
- "Take your meds" fires at 3am local time
|
- "Take your meds" fires at 3am local time
|
||||||
- "Today" means the wrong day
|
- "Today" means the wrong day
|
||||||
- Sleep predictions are off by hours
|
- 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
|
- Maintain cumulative CSV logs split by month as the authoritative record
|
||||||
- CSV columns (fixed order): Date,Time,TimeZone,Medication,Dosage
|
- CSV columns (fixed order): Date,Time,TimeZone,Medication,Dosage
|
||||||
- "Today"/"yesterday"/"tomorrow" always mean relative to currentTimezone
|
- "Today"/"yesterday"/"tomorrow" always mean relative to currentTimezone in
|
||||||
in daily-context.json — NEVER relative to system clock
|
daily-context.json — NEVER relative to system clock
|
||||||
- Always spell medication names correctly; silently correct transcription errors
|
- Always spell medication names correctly; silently correct transcription errors
|
||||||
|
|
||||||
## Daily Medications
|
## Daily Medications
|
||||||
|
|
||||||
One batch per calendar day unless explicitly confirmed otherwise. "Log my
|
One batch per calendar day unless explicitly confirmed otherwise. "Log my daily
|
||||||
daily meds" = log each as a separate row.
|
meds" = log each as a separate row.
|
||||||
|
|
||||||
**CRITICAL: Never trust hasTakenDailyMedsToday without verifying
|
**CRITICAL: Never trust hasTakenDailyMedsToday without verifying
|
||||||
dailyMedsTimestamp.**
|
dailyMedsTimestamp.**
|
||||||
@ -761,9 +765,9 @@ dailyMedsTimestamp.**
|
|||||||
|
|
||||||
**Ideal dosing window:** every 24h ±4h. Hard minimum: 14h between doses.
|
**Ideal dosing window:** every 24h ±4h. Hard minimum: 14h between doses.
|
||||||
|
|
||||||
| Medication | Dosage |
|
| Medication | Dosage |
|
||||||
| ------------ | ------ |
|
| ----------- | ------ |
|
||||||
| (your meds) | (dose) |
|
| (your meds) | (dose) |
|
||||||
|
|
||||||
## Interval-Based Medications
|
## Interval-Based Medications
|
||||||
|
|
||||||
@ -774,6 +778,7 @@ Scheduling anchored to last actual dose, NOT intended dates.
|
|||||||
| (med name) | (dose) | Every X days |
|
| (med name) | (dose) | Every X days |
|
||||||
|
|
||||||
**Missed dose rules:**
|
**Missed dose rules:**
|
||||||
|
|
||||||
- If missed, next dose date is unknown until the missed dose is taken and logged
|
- If missed, next dose date is unknown until the missed dose is taken and logged
|
||||||
- Interval restarts from actual ingestion timestamp
|
- Interval restarts from actual ingestion timestamp
|
||||||
- Missed doses block future scheduling
|
- Missed doses block future scheduling
|
||||||
@ -781,9 +786,9 @@ Scheduling anchored to last actual dose, NOT intended dates.
|
|||||||
## Safety Rules (HIGHEST PRIORITY)
|
## Safety Rules (HIGHEST PRIORITY)
|
||||||
|
|
||||||
1. Always triple-check before instructing any medication:
|
1. Always triple-check before instructing any medication:
|
||||||
- Last actual dose taken
|
- Last actual dose taken
|
||||||
- Required dosing interval
|
- Required dosing interval
|
||||||
- Current eligibility without overdose risk
|
- Current eligibility without overdose risk
|
||||||
2. If any ambiguity exists, **do not instruct dosing**
|
2. If any ambiguity exists, **do not instruct dosing**
|
||||||
3. Immediately block logging if same-day duplicate daily-med batch or other
|
3. Immediately block logging if same-day duplicate daily-med batch or other
|
||||||
overdose pattern appears
|
overdose pattern appears
|
||||||
@ -812,20 +817,20 @@ Scheduling anchored to last actual dose, NOT intended dates.
|
|||||||
### Overdue escalation:
|
### Overdue escalation:
|
||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
**CRITICAL: If daily meds are >26h since last dose, escalate aggressively.**
|
**CRITICAL: If daily meds are >26h since last dose, escalate aggressively.** Use
|
||||||
Use urgent notification channel if chat messages go unacknowledged.
|
urgent notification channel if chat messages go unacknowledged. Do not let this
|
||||||
Do not let this slide silently. Always include hours since last dose in
|
slide silently. Always include hours since last dose in reminders (e.g. "daily
|
||||||
reminders (e.g. "daily meds overdue — last dose was 27h ago").
|
meds overdue — last dose was 27h ago").
|
||||||
```
|
```
|
||||||
|
|
||||||
### Why the double-check on the boolean:
|
### Why the double-check on the boolean:
|
||||||
|
|
||||||
The daily-context.json has a `hasTakenDailyMedsToday` boolean AND a
|
The daily-context.json has a `hasTakenDailyMedsToday` boolean AND a
|
||||||
`dailyMedsTimestamp`. A midnight-reset cron flips the boolean to false. But
|
`dailyMedsTimestamp`. A midnight-reset cron flips the boolean to false. But if
|
||||||
if the user is in a timezone ahead of the server, the boolean may reset
|
the user is in a timezone ahead of the server, the boolean may reset before
|
||||||
before their actual "today" ends — or after it began. The rule: **always
|
their actual "today" ends — or after it began. The rule: **always verify the
|
||||||
verify the timestamp falls on today's date in the user's timezone.** The
|
timestamp falls on today's date in the user's timezone.** The boolean is a
|
||||||
boolean is a convenience hint, not the source of truth.
|
convenience hint, not the source of truth.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -851,8 +856,8 @@ Date,FlightNumber,Origin,Destination,Duration,Alliance
|
|||||||
```markdown
|
```markdown
|
||||||
## Flight Prep Blocks (daily)
|
## Flight Prep Blocks (daily)
|
||||||
|
|
||||||
Run `khal list today 7d`. For flights missing "shower and dress" /
|
Run `khal list today 7d`. For flights missing "shower and dress" / "travel to
|
||||||
"travel to airport" blocks, create them:
|
airport" blocks, create them:
|
||||||
|
|
||||||
- shower_start = flight_departure - airport_buffer - travel_buffer - 1h
|
- shower_start = flight_departure - airport_buffer - travel_buffer - 1h
|
||||||
- Airport buffer: 2h domestic, 2.5h international
|
- Airport buffer: 2h domestic, 2.5h international
|
||||||
@ -927,10 +932,10 @@ completed. Every session can read these.
|
|||||||
|
|
||||||
## Topics
|
## Topics
|
||||||
|
|
||||||
| Time | Topic | Session |
|
| Time | Topic | Session |
|
||||||
|------|-------|---------|
|
| ----- | ---------------------------- | ------- |
|
||||||
| 14:30 | Discussed PR review workflow | main |
|
| 14:30 | Discussed PR review workflow | main |
|
||||||
| 16:00 | Medication logged | main |
|
| 16:00 | Medication logged | main |
|
||||||
|
|
||||||
## Notes
|
## Notes
|
||||||
|
|
||||||
@ -993,15 +998,19 @@ stay quiet.
|
|||||||
# HEARTBEAT.md
|
# HEARTBEAT.md
|
||||||
|
|
||||||
## Inbox Check (PRIORITY)
|
## Inbox Check (PRIORITY)
|
||||||
|
|
||||||
(check notifications, issues, emails — whatever applies)
|
(check notifications, issues, emails — whatever applies)
|
||||||
|
|
||||||
## Flight Prep Blocks (daily)
|
## Flight Prep Blocks (daily)
|
||||||
|
|
||||||
(create calendar prep blocks for upcoming flights)
|
(create calendar prep blocks for upcoming flights)
|
||||||
|
|
||||||
## Open Projects Review
|
## Open Projects Review
|
||||||
|
|
||||||
(check project status, take next steps, or ask if blocked)
|
(check project status, take next steps, or ask if blocked)
|
||||||
|
|
||||||
## Workspace Sync
|
## Workspace Sync
|
||||||
|
|
||||||
(commit and push workspace changes)
|
(commit and push workspace changes)
|
||||||
|
|
||||||
## Rules
|
## Rules
|
||||||
@ -1013,6 +1022,7 @@ stay quiet.
|
|||||||
## Output Rules
|
## Output Rules
|
||||||
|
|
||||||
Never send internal thinking or status narration to user's DM. Output should be:
|
Never send internal thinking or status narration to user's DM. Output should be:
|
||||||
|
|
||||||
- HEARTBEAT_OK (if nothing needs attention)
|
- HEARTBEAT_OK (if nothing needs attention)
|
||||||
- A direct question or alert (if action needed)
|
- A direct question or alert (if action needed)
|
||||||
- Work narration → send to a status channel via message tool
|
- Work narration → send to a status channel via message tool
|
||||||
@ -1022,13 +1032,13 @@ Never send internal thinking or status narration to user's DM. Output should be:
|
|||||||
|
|
||||||
```json
|
```json
|
||||||
{
|
{
|
||||||
"lastChecks": {
|
"lastChecks": {
|
||||||
"email": 1703275200,
|
"email": 1703275200,
|
||||||
"calendar": 1703260800,
|
"calendar": 1703260800,
|
||||||
"weather": null,
|
"weather": null,
|
||||||
"gitea": 1703280000
|
"gitea": 1703280000
|
||||||
},
|
},
|
||||||
"lastWeeklyDocsReview": "2026-02-24"
|
"lastWeeklyDocsReview": "2026-02-24"
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -1036,12 +1046,14 @@ Never send internal thinking or status narration to user's DM. Output should be:
|
|||||||
|
|
||||||
```markdown
|
```markdown
|
||||||
**Use heartbeat when:**
|
**Use heartbeat when:**
|
||||||
|
|
||||||
- Multiple checks can batch together
|
- Multiple checks can batch together
|
||||||
- You need conversational context from recent messages
|
- You need conversational context from recent messages
|
||||||
- Timing can drift slightly (every ~30 min is fine)
|
- Timing can drift slightly (every ~30 min is fine)
|
||||||
- You want to reduce API calls by combining periodic checks
|
- You want to reduce API calls by combining periodic checks
|
||||||
|
|
||||||
**Use cron when:**
|
**Use cron when:**
|
||||||
|
|
||||||
- Exact timing matters ("9:00 AM sharp every Monday")
|
- Exact timing matters ("9:00 AM sharp every Monday")
|
||||||
- Task needs isolation from main session history
|
- Task needs isolation from main session history
|
||||||
- You want a different model or thinking level for the task
|
- 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
|
- When nothing is assigned to me, my Gitea work is done
|
||||||
- PRs assigned to user = their queue, not my backlog
|
- PRs assigned to user = their queue, not my backlog
|
||||||
|
|
||||||
Workflow: issue → branch → PR "(closes #X)" → review/rework → assign user
|
Workflow: issue → branch → PR "(closes #X)" → review/rework → assign user when
|
||||||
when all checks pass + reviewed.
|
all checks pass + reviewed.
|
||||||
|
|
||||||
### Rules
|
### Rules
|
||||||
|
|
||||||
@ -1082,10 +1094,10 @@ when all checks pass + reviewed.
|
|||||||
|
|
||||||
### Notification poller:
|
### Notification poller:
|
||||||
|
|
||||||
A Python script that polls the Gitea notifications API and injects events
|
A Python script that polls the Gitea notifications API and injects events into
|
||||||
into OpenClaw sessions. It runs via launchd/systemd. Ask me for the full
|
OpenClaw sessions. It runs via launchd/systemd. Ask me for the full source code
|
||||||
source code if you want to set this up — I can share it (it's a
|
if you want to set this up — I can share it (it's a general-purpose tool with no
|
||||||
general-purpose tool with no PII).
|
PII).
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
@ -1099,8 +1111,7 @@ For complex coding tasks, spawn isolated sub-agents.
|
|||||||
### Sub-Agent Git Isolation (MANDATORY)
|
### Sub-Agent Git Isolation (MANDATORY)
|
||||||
|
|
||||||
- NEVER let multiple sub-agents share the same git clone
|
- NEVER let multiple sub-agents share the same git clone
|
||||||
- Each sub-agent MUST clone to a unique temporary directory
|
- Each sub-agent MUST clone to a unique temporary directory (e.g. `mktemp -d`)
|
||||||
(e.g. `mktemp -d`)
|
|
||||||
- When spawning, always instruct: `cd $(mktemp -d) && git clone <url> . && ...`
|
- When spawning, always instruct: `cd $(mktemp -d) && git clone <url> . && ...`
|
||||||
- Dirty working directories cause false CI results
|
- 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
|
### Know When to Speak
|
||||||
|
|
||||||
**Respond when:**
|
**Respond when:**
|
||||||
|
|
||||||
- Directly mentioned or asked a question
|
- Directly mentioned or asked a question
|
||||||
- You can add genuine value (info, insight, help)
|
- You can add genuine value (info, insight, help)
|
||||||
- Something witty/funny fits naturally
|
- Something witty/funny fits naturally
|
||||||
- Correcting important misinformation
|
- Correcting important misinformation
|
||||||
|
|
||||||
**Stay silent when:**
|
**Stay silent when:**
|
||||||
|
|
||||||
- Just casual banter between humans
|
- Just casual banter between humans
|
||||||
- Someone already answered the question
|
- Someone already answered the question
|
||||||
- Your response would just be "yeah" or "nice"
|
- Your response would just be "yeah" or "nice"
|
||||||
@ -1163,6 +1176,7 @@ Quality > quantity.
|
|||||||
### React Like a Human
|
### React Like a Human
|
||||||
|
|
||||||
Use emoji reactions naturally:
|
Use emoji reactions naturally:
|
||||||
|
|
||||||
- Appreciate something but don't need to reply → 👍, ❤️
|
- Appreciate something but don't need to reply → 👍, ❤️
|
||||||
- Something made you laugh → 😂
|
- Something made you laugh → 😂
|
||||||
- Interesting/thought-provoking → 🤔, 💡
|
- Interesting/thought-provoking → 🤔, 💡
|
||||||
@ -1180,12 +1194,12 @@ Never lose a rule or preference your human states:
|
|||||||
```markdown
|
```markdown
|
||||||
### Requirement Capture (MANDATORY)
|
### Requirement Capture (MANDATORY)
|
||||||
|
|
||||||
- **Every single requirement, rule, preference, or instruction the user
|
- **Every single requirement, rule, preference, or instruction the user provides
|
||||||
provides MUST be captured in the daily memory file immediately**
|
MUST be captured in the daily memory file immediately**
|
||||||
- This includes: project rules, workflow preferences, corrections, new
|
- This includes: project rules, workflow preferences, corrections, new policies,
|
||||||
policies, technical decisions
|
technical decisions
|
||||||
- If the user says something should be done a certain way, write it down
|
- If the user says something should be done a certain way, write it down in
|
||||||
in memory/YYYY-MM-DD.md AND in MEMORY.md if it's a standing rule
|
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.
|
- 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
|
## PII Output Routing — Audience-Aware Responses
|
||||||
|
|
||||||
A critical security pattern: **the audience determines what you can say, not
|
A critical security pattern: **the audience determines what you can say, not who
|
||||||
who asked.** If your human asks for a sitrep (or any PII-containing info) in a
|
asked.** If your human asks for a sitrep (or any PII-containing info) in a group
|
||||||
group channel, you can't just dump it there — other people can read it.
|
channel, you can't just dump it there — other people can read it.
|
||||||
|
|
||||||
### AGENTS.md / checklist prompt:
|
### 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:
|
### Why this matters:
|
||||||
|
|
||||||
This is a real failure mode. If someone asks "sitrep" in a group channel and
|
This is a real failure mode. If someone asks "sitrep" in a group channel and you
|
||||||
you respond with medication names, partner details, travel dates, and hotel
|
respond with medication names, partner details, travel dates, and hotel names —
|
||||||
names — you just leaked all of that to everyone in the channel. The human
|
you just leaked all of that to everyone in the channel. The human asking is
|
||||||
asking is authorized to see it; the channel audience is not. Always check
|
authorized to see it; the channel audience is not. Always check WHERE you're
|
||||||
WHERE you're responding, not just WHO asked.
|
responding, not just WHO asked.
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
## General Tips
|
## General Tips
|
||||||
|
|
||||||
### Bias toward action
|
### 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
|
### Checklists over trust
|
||||||
|
|
||||||
For safety-critical operations (meds, deployments, external communications),
|
For safety-critical operations (meds, deployments, external communications),
|
||||||
maintain checklists in `memory/checklist-*.md` and reference them from
|
maintain checklists in `memory/checklist-*.md` and reference them from
|
||||||
AGENTS.md. The agent reads the checklist before acting.
|
AGENTS.md. The agent reads the checklist before acting.
|
||||||
|
|
||||||
### State repo
|
### State repo
|
||||||
|
|
||||||
Keep your workspace in a git repo that auto-syncs. This gives you version
|
Keep your workspace in a git repo that auto-syncs. This gives you version
|
||||||
history and recovery:
|
history and recovery:
|
||||||
|
|
||||||
@ -1250,6 +1267,7 @@ history and recovery:
|
|||||||
## On Errors
|
## On Errors
|
||||||
|
|
||||||
When something goes wrong:
|
When something goes wrong:
|
||||||
|
|
||||||
1. Identify what input caused the wrong output
|
1. Identify what input caused the wrong output
|
||||||
2. Fix the input (rule, checklist, prompt, automation)
|
2. Fix the input (rule, checklist, prompt, automation)
|
||||||
3. Move on
|
3. Move on
|
||||||
@ -1262,9 +1280,9 @@ No apologies. No promises. Fix the system.
|
|||||||
```markdown
|
```markdown
|
||||||
## On Integrity
|
## On Integrity
|
||||||
|
|
||||||
Never cheat. When a check fails, fix the code — don't weaken the check.
|
Never cheat. When a check fails, fix the code — don't weaken the check. When a
|
||||||
When a test fails, fix the bug — don't loosen the assertion. When a linter
|
test fails, fix the bug — don't loosen the assertion. When a linter flags
|
||||||
flags something, fix the finding — don't suppress the rule.
|
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,
|
for OpenClaw agents: workspace bootstrapping, daily context state files,
|
||||||
sitrep (situation report) prompts, sleep tracking, medication tracking,
|
sitrep (situation report) prompts, sleep tracking, medication tracking,
|
||||||
timezone-aware location tracking, flight/travel logging, memory architecture,
|
timezone-aware location tracking, flight/travel logging, memory architecture,
|
||||||
heartbeat configuration, Gitea integration, sub-agent management, and
|
heartbeat configuration, Gitea integration, sub-agent management, and security
|
||||||
security patterns.
|
patterns.
|
||||||
|
|
||||||
## Purpose
|
## 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
|
- **Credentials:** API keys, tokens, passwords, SSH keys, webhook URLs with
|
||||||
secrets, ntfy topic IDs
|
secrets, ntfy topic IDs
|
||||||
- **Actual log data:** medication logs, sleep logs, flight logs, location logs,
|
- **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
|
- **Infrastructure details:** specific hostnames, IP addresses, Tailscale/VPN
|
||||||
configurations, server names
|
configurations, server names
|
||||||
- **Private repository contents:** code from private repos, issue contents,
|
- **Private repository contents:** code from private repos, issue contents, PR
|
||||||
PR discussions
|
discussions
|
||||||
- **Financial information:** account numbers, transaction details
|
- **Financial information:** account numbers, transaction details
|
||||||
|
|
||||||
### Pre-Publish Checklist
|
### 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,
|
1. Scans the diff for PII patterns (names, emails, addresses, phone numbers,
|
||||||
coordinates, hostnames, API keys, tokens)
|
coordinates, hostnames, API keys, tokens)
|
||||||
2. Verifies all examples use placeholder values (`YOUR-TOPIC-ID`,
|
2. Verifies all examples use placeholder values (`YOUR-TOPIC-ID`, `example.com`,
|
||||||
`example.com`, `(your meds)`, etc.)
|
`(your meds)`, etc.)
|
||||||
3. Confirms no real log data is included — only format specifications
|
3. Confirms no real log data is included — only format specifications
|
||||||
4. Reviews for infrastructure leaks (internal hostnames, IP ranges, VPN details)
|
4. Reviews for infrastructure leaks (internal hostnames, IP ranges, VPN details)
|
||||||
5. Gets explicit approval from the repo owner for new document types
|
5. Gets explicit approval from the repo owner for new document types
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user