A drift scanner for OpenClaw agent workspaces. Detects stale tracker entries, broken references, contradictions between documentation and reality, orphaned files, and cron/skill mismatches.
Never applies fixes. Findings are reported for human review and explicit approval. By default, the script also appends a concise audit summary to today's daily memory log; pass --no-log for a fully read-only run.
| Area | Checks |
|---|---|
| PROJECTS.md | Stale dates, relative-time rot, missing file references, contradictions with MEMORY.md, ghost projects |
| MEMORY.md | Line count, stale model/plugin claims, contradictions, uncurated auto-promotion sections |
| HEARTBEAT.md | Broken file references, trial expiry, vault path drift |
| TRIALS.md | Evaluation dates passed or approaching |
| Cron jobs | Skill/cron mismatches |
| Skills | Skills with no cron registration (on-demand vs orphaned) |
| Workspace root | Backup files, reviewed archive/move candidates, dynamic OpenClaw-managed file signals, unclassified root markdown-like files |
| Daily logs | Today's file existence |
| Dreaming | Cron delivery configuration vs DREAMS.md canonical status |
| Wiki hygiene | INFO-only guardrails for missing/tiny wiki sources, generated lint/contradiction reports, and source-sync/state anomalies |
# Clone into your OpenClaw workspace skills directory
git clone https://github.com/rimpe/drift-audit.git ~/.openclaw/workspace/skills/drift-audit
# Or copy manually
cp -r drift-audit ~/.openclaw/workspace/skills/# Run the audit and append a daily-log summary
python3 ~/.openclaw/workspace/skills/drift-audit/scripts/audit.py
# Fully read-only run: print report only, no daily-log summary
python3 ~/.openclaw/workspace/skills/drift-audit/scripts/audit.py --no-log
# Review OpenClaw dreaming auto-promotions in MEMORY.md
python3 ~/.openclaw/workspace/skills/drift-audit/scripts/review_promotions.py
# Or invoke via OpenClaw skill system
openclaw skills invoke drift-auditStructured report with severity levels:
- 🔴 CRITICAL: Data integrity risk — contradictions, missing referenced files, unreadable required state
- 🟡 WARNING: Stale data, approaching deadlines, drifting trackers
- 🟢 INFO: Observations, cleanup opportunities, architectural notes
Example:
🧭 Drift Audit Report
Generated: 2026-04-24 19:32
Summary: 8 critical, 23 warnings, 17 info
🔴 [CRITICAL] MEMORY.md
Line: 102
Claim: Claims firewall is DISABLED
Reality: PROJECTS.md says firewall was enabled
Fix: Reconcile the two files
| Code | Meaning |
|---|---|
| 0 | No critical findings |
| 1 | At least one critical finding |
drift-audit reports state, it doesn't fix it. When acting on a finding, follow this rule:
Never rewrite past daily logs. Past memory/YYYY-MM-DD.md files are an event record — they capture what was true at that moment, including statements that later turned out wrong. Resolving drift by editing the current state file (MEMORY.md, PROJECTS.md, HEARTBEAT.md, TRIALS.md) and appending a correction to today's daily log preserves the historical signal. Overwriting a past log destroys it.
Curated state files are fair game to edit or delete stale sections. Daily logs are append-only history.
OpenClaw dreaming appends strong short-term candidates to MEMORY.md under ## Promoted From Short-Term Memory (...). Treat these sections as a temporary long-term-memory inbox:
- Fresh sections (≤48h) are INFO.
- Unreviewed stale sections (>48h) are WARNING.
- Use
scripts/review_promotions.pyto inspect candidates and source lines. - Resolve each section by curating durable items into normal
MEMORY.mdprose, dismissing noise, or deferring with a reason. - Optional review marker after resolution:
<!-- openclaw-promotion-reviewed:YYYY-MM-DD curated|dismissed|deferred -->
Add to cron/jobs.json for weekly automated scanning:
{
"name": "Weekly Drift Audit",
"schedule": { "expr": "0 15 * * 0", "tz": "Europe/Helsinki" },
"payload": {
"message": "Invoke the drift-audit skill"
},
"delivery": {
"mode": "announce",
"channel": "telegram",
"to": "YOUR_TOPIC"
}
}Edit scripts/audit.py to adjust:
- Root file classification sets in
scripts/audit.py(CORE_MARKDOWN_FILES,OPENCLAW_MANAGED_ROOT_FILES, archive/move candidates) - Date thresholds for staleness
- Severity mappings
Root cleanup is conservative. The audit scans root *.md and observed backup siblings *.md.*, but it does not scan claws_vault/**/*.md as root clutter. For unknown root files, deterministic checks come first: static classification, rollback/trial references, and installed OpenClaw/runtime string references. If ownership is still unclear, use AI/web triage to classify the file as likely OpenClaw-managed, user note, backup, project doc, or archive candidate. AI/web output is advisory only: never auto-delete or auto-move based on it.
- Python 3.8+
- Read access to
~/.openclaw/workspace/and~/.openclaw/cron/jobs.json
MIT
Issues and PRs welcome. This was built for the OpenClaw agent system but adapts to any workspace with:
PROJECTS.md(project tracker)MEMORY.md(long-term memory)HEARTBEAT.md/TRIALS.md(process docs)memory/(daily logs)skills/(skill directory)