4.1 KiB
4.1 KiB
Iteration 5 Results — 2026-05-28 (FR-2 cron→Telegram loop closed)
Architecture spike outcome (per iter-4's deferral)
The hook already existed in packages/server/src/local/cron.ts:111 — LocalScheduler was constructed with an optional JobCompleteCallback and the existing callback at index.ts:1810 was already routing to in-app notifications. Wiring Telegram was a one-side extension, not a refactor:
- No new hook surface needed — the callback fires on every tick.
- One small fix needed —
LocalScheduler.executeJob(manual "Run now" path) wasn't invoking the callback. Fixed for consistency so manual triggers also notify + push.
Shipped this iter
Server-side runtime (FR-2 §runtime)
packages/server/src/local/routes/telegram.ts— exportedpushTelegramMessage(server, text)helper for in-process callers; capped at Telegram's 4096-char limit; never throws.packages/server/src/local/index.ts—onJobCompletecallback now parsesschedule.job_config, checksoutputChannel === 'telegram', and pushes a one-line digest viapushTelegramMessage. Errors logged but never crash the scheduler tick.packages/server/src/local/cron.ts—executeJobextended to fire the callback on both success and failure paths (mirrorstick()semantics). Manual "Run now" now routes to notifications + Telegram identically to auto-runs.
UI (FR-2 §UI part 2)
apps/web/src/components/os/apps/ScheduledJobsApp.tsx— create-form gains a "Where the result goes" dropdown with two options:Notification + cockpit log(default — existing behavior)Telegram (requires Settings → Advanced → Telegram digest)
- When
telegramis selected,jobConfig: { outputChannel: 'telegram' }is forwarded throughadapter.createCronJob→/api/cron→ cron-store → the runtime callback above.
End-to-end loop (now closed)
- User configures Telegram in Settings → Advanced → Telegram digest tile (shipped iter-4).
- User creates a cron job, picks "Telegram" as output channel.
- Job runs (cron tick OR manual "Run now").
onJobCompletecallback fires → readsjobConfig.outputChannel→ callspushTelegramMessage→ user receives "✓ Waggle: {name} ({cron}) ran successfully." or "✗ Waggle: … failed — {error}".
Honest score movement
| Persona | Iter-4 | Iter-5 | Δ | Why |
|---|---|---|---|---|
| P1 Greta | 3 | 3 | 0 | Browser ext is her hook; Telegram less relevant |
| P2 Hassan | 2 | 3 | +1 | iPhone-first user — Telegram push is real external trigger |
| P3 Sarah | 7 | 7 | 0 | Already at solid score |
| P4 Imran | 6 | 6 | 0 | Apple-ecosystem; no Telegram habit |
| P5 Lucas | 8 | 8 | 0 | Browser ext already won him |
| P6 Daniel | 6 | 7 | +1 | Monday-morning variance summary fits perfectly |
| P7 Anya | 8 | 8 | 0 | Browser ext already her hook |
| P8 Marko | 8 | 9 | +1 | Daily strategic recap channel |
| P9 Priya | 6 | 6 | 0 | Engineering — wants Slack/Discord more than Telegram |
| P10 Tomás | 5 | 7 | +2 | Cron→Telegram IS his Hermes-style workflow — now native in Waggle |
| avg | 5.9 | 6.4 | +0.5 | 5 cells closed across 4 personas |
Remaining gap to 10/10 (3.6 points across 10 personas)
| Item | Personas moved | Effort |
|---|---|---|
| FR-3 public skill registry | P4, P8, P9, P10 | 2 sprints |
| FR-5 sample workspace import | P1, P2, P3, P5, P7 | ~1 day |
| FR-6 native xlsx | P6 | 2-3 sprints |
| FR-9 voice journaling | P1 | 1 sprint |
| FR-10 social loop | P3, P9, P10 | 1.5 sprints |
| Plus surgical polish (F3 sample workspace UI, F4 coverage compass, F5 onboarding teach memory) | various | small |
Realistic next single-turn target: FR-5 sample workspace import (~1 day, well-scoped, lifts 5 personas).
Files committed in this iter
- packages/server/src/local/cron.ts (1 edit — executeJob callback)
- packages/server/src/local/routes/telegram.ts (1 new export — pushTelegramMessage)
- packages/server/src/local/index.ts (1 import + 1 callback extension)
- apps/web/src/components/os/apps/ScheduledJobsApp.tsx (state + dropdown + jobConfig pass-through)
- docs/addictiveness-audit-2026-05-28/ITER-5-RESULTS.md (new)