Repository navigation
feat(proactive-notify): add queue, voice, macos_notif action modules - #1129
bassilkhilo-ag2 wants to merge 1 commit into
Conversation
liususan091219
left a comment
There was a problem hiding this comment.
BLOCKING
Same build_log.md leak as #1124 / #1131. Please drop it.
-
build_log.md +114/-0— identical Pass 207-211 content (branch names, commit SHAs, pending pushes forport/*+merge/stando-sync). Per-instance operational state; in.gitignore. Would overwrite/diverge the build_log.md from the prior author. -
Scope creep — title is
feat(proactive-notify): add queue, voice, macos_notif action modules. The 3 action modules + their test (actions/queue.py,actions/voice.py,actions/macos_notif.py,tests/proactive-notify-actions-queue-voice-notif.test.py) are scoped. Out of scope:src/health-check.py +14/-2andtests/health-check-bridge-multi-pid.test.py +88/-0— same edits as in #1131. Move them to one shared PR rather than duplicating into every branch.
NON-BLOCKING
The 3 action modules themselves look right:
macos_notif.py— explicit\\and"escaping before AppleScript interpolation is correct;subprocess.run(..., timeout=5)withFileNotFoundError/TimeoutExpired/CalledProcessErrorcovers the failure modes.voice.pywritesresults/proactive-{ts}.txt— matchestask-bridge.tspoll pattern.queue.pyJSONL append +mkdir(parents=True, exist_ok=True)is idempotent.
Question: in macos_notif.py, do you want a length cap on body/title before passing to osascript? macOS notification banners truncate around ~250 chars anyway, but very long bodies could blow the command-line length budget. Probably fine in practice — flag for awareness, not required.
VasiliyRad
left a comment
There was a problem hiding this comment.
Agree with Susan's review — the three action modules are solid, but the PR needs cleanup before merge.
Blocking (same as Susan's):
- Drop
build_log.md— per-instance operational state, gitignored, would conflict with other instances. - Move
src/health-check.pyandtests/health-check-bridge-multi-pid.test.pyout of this branch. They duplicate #1131 and are unrelated to proactive-notify actions. One PR per concern.
Action modules look good (non-blocking notes):
queue.py: JSONL append with idempotentmkdirand OSError fallback — clean.voice.py: Writes the standardresults/proactive-{ts}.txtpath that task-bridge polls — correct integration.macos_notif.py: AppleScript escaping for\and"is correct.subprocess.runwithtimeout=5and all three exception handlers (FileNotFoundError,TimeoutExpired,CalledProcessError) cover the failure surface. Susan's note about a length cap is fair but not blocking.- Test file: 34 tests, thorough coverage including error paths and escaping edge cases.
Once build_log.md and the health-check changes are dropped, this is ready to approve.
Co-Authored-By: Claude Opus 4.7 (1M context) noreply@anthropic.com
Three action channels were referenced in channel-policy.yaml.example
but had no implementation — any ping routed to them failed with
ModuleNotFoundError at runtime:
- queue: appends to state/queue.jsonl (fyi tier + quiet-hours fallback)
- voice: writes results/proactive-{ts}.txt for voice-agent narration
- macos_notif: fires osascript desktop notification, escapes AppleScript
string literals to prevent injection via event body
34 tests across all three modules — all passing.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2172ef0 to
be59874
Compare
|
Rebased to clean diff — removed 3 bundled commits that were carrying
All 34 tests still pass. Re-requesting review. |
Problem
channel-policy.yaml.examplereferences three action channel names —queue,voice, andmacos_notif— but none of those modules existedunder
skills/proactive-notify/scripts/actions/. The runner doesimportlib.import_module(f"actions.{channel}"), so any ping routed tothese channels failed with
ModuleNotFoundErrorat runtime:fyi-tier pings: default channel isqueue→ silent failure every runimportant→queue,critical→ stays assmsvoice→ failureSolution
Add three new action modules:
queue.pyAppends to
$WORKSPACE/skills/proactive-notify/state/queue.jsonlasnewline-delimited JSON entries (id, ts, ping name, urgency, body).
Idempotent directory creation; OSError returns
{"ok": False, "error": ...}.voice.pyWrites
$WORKSPACE/results/proactive-{ts}.txt— the standard pathpolled by
task-bridge.tsfor narration to the active voice session.macos_notif.pyFires
osascriptfor a macOS desktop notification banner. Properlyescapes backslashes and double-quotes in the body/title before
interpolating into the AppleScript string literal. Custom title via
SUTANDO_NOTIF_TITLEenv var (default: "Sutando"). CatchesFileNotFoundError,TimeoutExpired, andCalledProcessError.Tests
tests/proactive-notify-actions-queue-voice-notif.test.py— 34 tests:TestQueueModuleExists(2) +TestQueueSend(9): append logic, JSONLformat, directory creation, error propagation
TestVoiceModuleExists(2) +TestVoiceSend(7): file naming, content,dir creation, error path
TestMacosNotifModuleExists(3) +TestMacosNotifSend(11): osascriptcall shape, title env override, all failure modes, injection escaping
All 34 pass on Python 3.9.
Checklist
queue.py— fyi + quiet-hours sinkvoice.py— voice session narrationmacos_notif.py— desktop notification banner🤖 Generated with Claude Code