Skip to content

fix(pebble): ASCII-coerce ntfy title; disambiguate STT against KB folders#73

Merged
max-tet merged 1 commit into
mainfrom
fix/ntfy-ascii-title
May 17, 2026
Merged

fix(pebble): ASCII-coerce ntfy title; disambiguate STT against KB folders#73
max-tet merged 1 commit into
mainfrom
fix/ntfy-ascii-title

Conversation

@ClaydeCode
Copy link
Copy Markdown
Owner

Summary

  • Bug: Pebble request `c37ef27f` (2026-05-17 18:37) finished successfully and wrote `inbox/thomas_stegger_note.md`, but the ntfy notification with title `"Thomas Stegger — plant prefs saved"` was silently dropped:
    ntfy POST failed: 'ascii' codec can't encode character '—' in position 15: ordinal not in range(128)
    
    httpx encodes header values as latin-1, so any Unicode character outside that range (em dash, smart quotes, ellipsis, NBSP, emoji, …) raises `UnicodeEncodeError` before the request goes out. Watch shows "delivered" (enqueue 200), then nothing — so it looks like Clayde swallowed the call.
  • Fix: Normalise common typographic Unicode in `NotificationPayload.title` (em/en dash, smart quotes, ellipsis, NBSP) and ASCII-replace anything left over. Done in the field validator, so all callers (parsed Claude tail, framework fallback titles) are covered. Applied before length clamping so `…` → `...` doesn't blow past 40 chars.
  • Bonus: Tighten the Pebble system prompt so STT errors are disambiguated against the KB's real folder layout. Worked example: `"after people and tree for my brother-in-law"` → `"add a people entry for my brother-in-law"`, because `people/` is a real top-level folder and "after" / "tree" are plausible phonetic neighbours of "add a" / "entry". Claude is told to `ls /home/clayde/knowledge_base` and to state the chosen interpretation in its narrative so a wrong guess is visible in the ntfy summary.

Test plan

  • `uv run pytest` — 368 passed locally
  • Added regression tests in `test_webhook_notify.py`: em dash, smart quotes, emoji, ASCII-coercion-before-clamp
  • Added prompt assertions in `test_webhook_skills.py`: KB-structure disambiguation guidance present
  • Manual: send a pebble whose summary will contain an em dash, confirm watch notification arrives

🤖 Generated with Claude Code

The ntfy `Title` header travels through httpx, which encodes headers as
latin-1. A title containing an em dash (e.g. "Thomas Stegger — plant
prefs saved") raises UnicodeEncodeError before the request leaves the
container, so the Pebble outcome notification is silently dropped — the
work itself completes, but the user never sees the confirmation on the
watch.

Coerce title input through a small translation table (em/en dash, smart
quotes, ellipsis, NBSP) and ASCII-replace anything left over in the
`NotificationPayload` field validator. Apply before length clamping so
multi-char replacements like "…" → "..." still fit the 40-char window.

Also tighten the Pebble system prompt to disambiguate speech-to-text
errors against the KB's actual folder layout. Worked example added so
Claude reaches for `ls /home/clayde/knowledge_base` and treats top-level
folders ("people", "specs", "inbox", ...) as candidate matches for
phonetically similar transcription tokens.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@max-tet max-tet merged commit f444ca8 into main May 17, 2026
3 checks passed
@max-tet max-tet deleted the fix/ntfy-ascii-title branch May 17, 2026 21:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants