From 96986e9809e10ef68f6ff89124588fe7a092af7f Mon Sep 17 00:00:00 2001 From: James Date: Mon, 23 Feb 2026 18:01:32 -0500 Subject: [PATCH] chore: auto-commit uncommitted changes --- AGENTS.md | 1 + MEMORY.md | 9 +++++++-- memory/2026-02-23.md | 24 ++++++++++++++++++++++++ memory/claude-usage.db | Bin 40960 -> 45056 bytes memory/claude-usage.json | 12 ++++++------ memory/git-audit-lastfull.txt | 2 +- memory/heartbeat-state.json | 2 +- 7 files changed, 40 insertions(+), 10 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 7fceb3d..f1fccae 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -261,6 +261,7 @@ Enter plan mode for ANY non-trivial task: - **JSONL is the ultimate recovery source** — `sessions_history` only returns post-compaction messages. For pre-compaction content, the full raw transcript lives at `~/.clawdbot/agents//sessions/*.jsonl`. NEVER say "that was lost in compaction" without checking it first. To read safely without blowing context: run a Python script via `exec` that tail-reads the last 400 lines, truncates each line to 2000 chars (appending `[...TRUNCATED]`), stops at 40k total chars accumulated, then reverses to chronological order. Only the printed output enters context (~10K tokens). If any lines were truncated, disclose it. - **Exhaust self-recovery before escalation** — Always try: (1) `memory/working-context.md` — fast path, (2) `sessions_history` for recent tool calls, (3) `memory_search` transcripts, (4) session JSONL for anything pre-compaction (see above). Only ask human for info that genuinely isn't in any of these. - **Never guess config changes** — Read the docs or source first. Backup the file before editing. A wrong config guess can take down a service; 30 seconds of reading prevents it. +- **Critical config = git-tracked + verified** — Any config that controls a public-facing service (mail, proxy, DNS) must be: (1) git-tracked on the server, (2) backed up with a timestamp before editing (not just `.bak` which gets overwritten), (3) verified working BEFORE moving on. "I restarted it" is not verification — check the actual service output (e.g. `openssl s_client` for TLS, `curl` for HTTP). Learned from: Stalwart cert section wiped during config repair → full day of email outage. - **When debugging cascades, question the feature** — If you're 3+ hours into debugging a "simple" integration (SnappyMail webmail, PHP-FPM, Docker hairpin NAT), step back. Ask: "Is this feature actually needed?" Sometimes the right answer is abandonment, not persistence. **Plan includes verification:** Use plan mode for verification steps too, not just building. "How will I prove this works?" is part of the plan. diff --git a/MEMORY.md b/MEMORY.md index 8580252..12a0793 100644 --- a/MEMORY.md +++ b/MEMORY.md @@ -406,13 +406,18 @@ Automated document processing pipeline for scanned paperwork. - Fix needed: pin `optimum==1.22.0` (newer removed BetterTransformer); `input_ids.to("cuda")` before generate() - Use case: batch document analysis, offline medical record processing (data stays local) -### Stalwart — Key Gotchas (Feb 18-22) +### Stalwart — Key Gotchas (Feb 18-23) - Account `name` field must equal the login username — not automatically derived from `emails` field - PATCH endpoint is broken in v0.15.5 — use DELETE + POST for account updates - **NO user webmail** — admin panel only (port 8880). All popular self-hosted webmail (Roundcube, SnappyMail) is PHP and painful to integrate. - YAML `!` at start of value = YAML tag indicator — passwords starting with `!` must be quoted - systemd EnvironmentFile: `!` in values also needs quoting -- Admin API: port 8880, `admin:agolM71pOwZBJhggROBDkn8R` via HTTP Basic at `http://127.0.0.1:8880/api/principal` +- Admin API: port 8880, `admin:JamesAdmin2026x` via HTTP Basic at `http://127.0.0.1:8880/api/` +- **TLS cert config requires `%{file:...}%` macro syntax** — bare file paths are treated as literal strings, NOT read as cert content: + - ✅ `cert = "%{file:/etc/letsencrypt/live/mail.jongsma.me/fullchain.pem}%"` + - ❌ `cert = "/etc/letsencrypt/live/mail.jongsma.me/fullchain.pem"` (silently falls back to rcgen self-signed) +- **LE cert via certbot DNS-01**: installed 2026-02-23, valid until 2026-05-24. Cloudflare token in `/root/.secrets/cloudflare.ini` on Zurich. Deploy hook at `/etc/letsencrypt/renewal-hooks/deploy/stalwart.sh` restarts Stalwart on renewal. +- **Config surgery warning**: if you edit config.toml with sed or Python, the `[certificate.*]` and `[lookup.default]` sections may get wiped — always verify after repair ### DNS Debugging — AdGuard Rewrite Rules (Feb 22) - Home DNS is **AdGuard Home** (not just HA at 192.168.1.252) diff --git a/memory/2026-02-23.md b/memory/2026-02-23.md index 19a76f0..aa59473 100644 --- a/memory/2026-02-23.md +++ b/memory/2026-02-23.md @@ -60,3 +60,27 @@ ### AGENTS.md Update - Added JSONL recovery method rule (from Ben Badejo tweet — the one useful insight) + +--- + +## Afternoon (4 PM ET) — Stalwart TLS Fix + +### Problem +- Johan + Roos both not receiving email +- Root cause: Stalwart was serving `rcgen self signed cert` (built-in dummy, expired 1975) on port 993 +- iPhone Mail was presenting trust dialog, refusing to connect +- Caused by: cert config section wiped from config.toml during night shift Python repair + +### Fix +- Installed certbot + python3-certbot-dns-cloudflare on Zurich +- Obtained LE cert for mail.jongsma.me + mail.inou.com via Cloudflare DNS-01 challenge +- Cert valid Feb 23 – May 24 2026, stored at /etc/letsencrypt/live/mail.jongsma.me/ +- Key lesson: Stalwart needs `%{file:/path}%` macro syntax, NOT bare file paths in cert config + - `cert = "%{file:/etc/letsencrypt/live/mail.jongsma.me/fullchain.pem}%"` ← correct + - `cert = "/etc/letsencrypt/live/mail.jongsma.me/fullchain.pem"` ← treated as literal string, doesn't work +- Added certbot deploy hook: /etc/letsencrypt/renewal-hooks/deploy/stalwart.sh → restarts stalwart on renewal +- Port 993 now serves valid LE cert, confirmed externally + +### Communications +- Emailed Roos from james@jongsma.me with reconnect instructions +- Signal'd Roos (+31646563377) asking if she got the email diff --git a/memory/claude-usage.db b/memory/claude-usage.db index 8097ad35286a6ffedb450bb4a243b6a0d066597a..4ea756c2fa22b10fe35b233e8e5241331e6618fb 100644 GIT binary patch delta 800 zcma)4J%|%Q7@gTovYDApzKfuE=WSe0MT?y7?p=&YasGf7XK_smSuFP8Y|SqLMJ_*J zcSyoorV$Pii$EMJZBj(Au(Gfa(RfALQ}9qw#2GR1NDv&R`rh}xdGCEw>nXK?(mWEZ zAcR=UJdZ0~ZyTa2?1}V^>&$9iZRnd)lXuX_Hpyb$W@OqEYgNyd^#I zkZh46xkgsVaYDnN!f#**uXw1?*Ys!{=~Asce5+kn=VsNUGFFnxTIVvBC6%C$eB;hD zEFAh~>t44R$5Oq2qkU3~2=XlqzE=CJU}#-DXc~=N2qiHddvcbtc1n6$UUKIHCO=bu z9o6&|bQ33#Kg=)qZ5LbTNR1vrc^F=D{jigWtm+N))5S# z2M?eQ>*7zXLDguKrxF~~;`%Y8QJTg_QN=?G^Npg!!}~Wd4$Ke>DooM;q?UG#kSQAS L(+wlXM$r5PCAPXG delta 398 zcmZp8z|?SnX@WFs0RsaA*F*(-#)6FrOZa)1_`d=L7&!TV^MBnesBoWuVgTpnAM)%1 zf_Y3paVGwwAZafC$NWb(D+=u3pM2b&Z*q7IuPjiMU4q$^(a6BaOxM6j*U%`$(A3Jn z$jZPZs(6zFivn{I%l*yl3E!DEPI$<;`F@Hjw^lA=0t5eZ{&W0W`RDLA^Jnn~@>}rB z^Rw~2<-5YSi*Es68($7z5T6B~++>b|Ei8;~Ja&^gCMa#@C_Kc@!oa{hYh&Xy=E(_# zyqgPa)-p;-GMh5Ntv3!a1lnx?vYw%B^S`7MjO@HXH&!s}PiAlUII+=uvwq_xzCfT* zFXK7}{%8DW_&4#-;IHFP;rHS<;1}cj!}o~q1m8NoDSTCY34CsRI($OBKX~u)9^qZZ zJAt>1H-^`VSA&<2=L^p*o&!9~czSq>cp|_Kyf9g*t_SEWp3S=^ws4_3%QD2k7#u1V RQH*Sp&(xc2zE)Af3;?TRauxsp diff --git a/memory/claude-usage.json b/memory/claude-usage.json index 1dd9267..2c3a6c6 100644 --- a/memory/claude-usage.json +++ b/memory/claude-usage.json @@ -1,9 +1,9 @@ { - "last_updated": "2026-02-23T17:00:01.538033Z", + "last_updated": "2026-02-23T23:00:02.126542Z", "source": "api", - "session_percent": 3, - "session_resets": "2026-02-23T20:00:00.486329+00:00", - "weekly_percent": 28, - "weekly_resets": "2026-02-28T19:00:00.486350+00:00", - "sonnet_percent": 32 + "session_percent": 18, + "session_resets": "2026-02-24T01:00:00.079774+00:00", + "weekly_percent": 31, + "weekly_resets": "2026-02-28T19:00:00.079814+00:00", + "sonnet_percent": 36 } \ No newline at end of file diff --git a/memory/git-audit-lastfull.txt b/memory/git-audit-lastfull.txt index 42da4a9..cce5d1a 100644 --- a/memory/git-audit-lastfull.txt +++ b/memory/git-audit-lastfull.txt @@ -1 +1 @@ -1771779729 +1771866132 diff --git a/memory/heartbeat-state.json b/memory/heartbeat-state.json index 75ed24d..4c5d2ce 100644 --- a/memory/heartbeat-state.json +++ b/memory/heartbeat-state.json @@ -14,6 +14,6 @@ "lastDocInbox": "2026-02-20T14:30:00.000Z", "lastTechScan": "2026-02-23T13:02:43.785Z", "lastMemoryReview": "2026-02-23T13:01:00.000000+00:00", - "lastIntraDayXScan": "2026-02-23T14:34:00.000000+00:00", + "lastIntraDayXScan": "2026-02-23T22:24:00.000000+00:00", "lastInouSuggestion": "2026-02-23T13:05:33.000000+00:00" } \ No newline at end of file