diff --git a/inbox-work/TASK-20260829-1600-notify.md b/inbox-work/TASK-20260829-1600-notify.md new file mode 100644 index 0000000..aa33089 --- /dev/null +++ b/inbox-work/TASK-20260829-1600-notify.md @@ -0,0 +1,30 @@ +# TASK: harness native SMS notifier — `[notify]` (alpha wiring, Redmine 522) + +## Context +Charles (2026-08-29): "wire the sms ping into the go harness for alpha." +He watches Redmine/Gitea/SMS today. The bash bridge (loop-sms-watch.sh) +covers the interim; THIS replaces it natively. Runs AFTER the bootstrap +turn (gated) — build on the containerized loop. + +## Scope +1. `[notify]` harness.toml section: + - smtp_host / smtp_user_ref / smtp_pass_ref / from (key refs: env: + or mpk: — keyproxy-ready per #497), rcpt = 8182807059@tmomail.net + (config, not hardcoded), min_severity (info|ok|warn). + - enabled=false default; absent section = zero behavior change. +2. Go notifier (stdlib net/smtp, STARTTLS; AUTH PLAIN/LOGIN): + - Events: turn complete (task id + title), turn failed (error class), + quota wall deferral, loop scan error, daemon start/stop. + - Message format mirrors ping-charles.sh: `[SEV MM-DD HH:MM MOPAC] ...` + - Rate limit: max N per window (config, default 20/hour) — never + SMS-flood; identical consecutive failures collapse with a counter. + - Send failures: log + queue in state (retry next event), never block + the loop; never include credential material (redaction rules). +3. Tests: fake SMTP server (table-driven): auth, STARTTLS skip option, + event mapping, rate-limit collapse, queue+retry. +4. Wire the alpha container config (notify enabled once Charles drops + SMTP creds in the env-file tonight); document in runbook. + +## Deliverable +`REPORT-20260829-1600-notify.md` in `~/.coordinate/inbox-pmo/`: config +surface, event list, test results, exact env-file keys Charles fills in. diff --git a/log.md b/log.md index d8b93c8..613283c 100644 --- a/log.md +++ b/log.md @@ -88,3 +88,4 @@ 2026-08-29T06:20:17-05:00 | PMO | identity model ticket filed (linux runtime + cloudron acting, N per account); 497 corrected 2026-08-29T06:21:06-05:00 | PMO | identity model FINAL: 1:1 linux->BW vault (cloudron+3rd-party entries); acting identity selected per task/turn, stamped on all actions + usage 2026-08-29T06:26:47-05:00 | PMO | ALPHA LIVE: loop autonomous (520 done New->Resolved+note, 519 running); q12 killed; q14 CLI keeps running; tool-widening ticket filed Immediate +2026-08-29T06:29:44-05:00 | PMO | bootstrap turn dispatched (q15: container+tool-widening, FINAL crush turn); ping-charles.sh ready (needs SMTP creds tonight); loop alpha continues autonomous diff --git a/logs/loop-alpha.log b/logs/loop-alpha.log index 18310eb..e5920bf 100644 --- a/logs/loop-alpha.log +++ b/logs/loop-alpha.log @@ -35,3 +35,6 @@ harness: loop: refresh failed for 519: redmine HTTP 502: mopac-study -> glm-4.7-flash +harness: REPORT reports/REPORT-demo-518-20260829-113010.md +harness: loop: status New -> Resolved on #518 +harness: loop: noted REPORT on #518 diff --git a/logs/q-redmine-cli.log b/logs/q-redmine-cli.log index 89bb9e9..c830349 100644 --- a/logs/q-redmine-cli.log +++ b/logs/q-redmine-cli.log @@ -1 +1 @@ -I have full context: sibling pattern (mopac-bitwarden-go), harness fake-server test style, PMO python glue to replace, creds at `~/.creds/redmine.env`, Redmine at projects.knownelement.com. Setting up the work plan.Toolchain verified. Creating the repo via Gitea API (idempotent check first):Repo created. Cloning and seeding with LICENSE:Harness done. Now TDD config package — tests first (red):Red confirmed. Implementation:Green. Two atomic commits:Now the core piece. First the stateful fake Redmine server (test infrastructure, harness-style):Now the library test suite (red first): \ No newline at end of file +I have full context: sibling pattern (mopac-bitwarden-go), harness fake-server test style, PMO python glue to replace, creds at `~/.creds/redmine.env`, Redmine at projects.knownelement.com. Setting up the work plan.Toolchain verified. Creating the repo via Gitea API (idempotent check first):Repo created. Cloning and seeding with LICENSE:Harness done. Now TDD config package — tests first (red):Red confirmed. Implementation:Green. Two atomic commits:Now the core piece. First the stateful fake Redmine server (test infrastructure, harness-style):Now the library test suite (red first):Red confirmed (library absent). Fixing fake's query type, then writing the library: \ No newline at end of file diff --git a/scripts/loop-sms-watch.sh b/scripts/loop-sms-watch.sh new file mode 100755 index 0000000..86c4a0e --- /dev/null +++ b/scripts/loop-sms-watch.sh @@ -0,0 +1,21 @@ +#!/usr/bin/env bash +# loop-sms-watch.sh — bridge watcher: tail the alpha loop log and SMS +# Charles on milestones via ping-charles.sh (queues until SMTP wired). +# Superseded by the harness native [notify] notifier (ticket 522) once built. +set -uo pipefail +LOG="$HOME/.coordinate/logs/loop-alpha.log" +PING="$HOME/.coordinate/scripts/ping-charles.sh" +tail -n 0 -F "$LOG" 2>/dev/null | while read -r line; do + case "$line" in + *"loop: dispatch"*) + id=$(echo "$line" | grep -o 'dispatch [0-9]*' | grep -o '[0-9]*') + "$PING" "loop dispatched #$id" info >/dev/null 2>&1 || true ;; + *"noted REPORT"*) + id=$(echo "$line" | grep -o 'REPORT on #[0-9]*' | grep -o '[0-9]*$') + "$PING" "turn COMPLETE #$id — check redmine" ok >/dev/null 2>&1 || true ;; + *"status"*) + "$PING" "status transition: $line" info >/dev/null 2>&1 || true ;; + *FAIL*|*error*|*quota wall*|*deferred*) + "$PING" "loop issue: $line" warn >/dev/null 2>&1 || true ;; + esac +done