#16321: Fix #12767: suppress HEARTBEAT_OK leakage in Telegram DM replies
channel: whatsapp-web
agents
stale
size: S
Cluster:
HEARTBEAT_OK Suppression Fixes
## Summary
- Problem: `HEARTBEAT_OK` acknowledgements could leak through the embedded runner payload path and show up in Telegram DM.
- Why it matters: heartbeat ack tokens are control signals and should be silently discarded when no user-facing content exists.
- What changed: added heartbeat-token normalization in embedded payload construction, plus regression tests.
- What did NOT change (scope boundary): no channel transport logic, no heartbeat scheduler behavior, no config defaults.
## Change Type (select all)
- [x] Bug fix
- [ ] Feature
- [ ] Refactor
- [ ] Docs
- [ ] Security hardening
- [ ] Chore/infra
## Scope (select all touched areas)
- [ ] Gateway / orchestration
- [ ] Skills / tool execution
- [ ] Auth / tokens
- [ ] Memory / storage
- [x] Integrations
- [ ] API / contracts
- [ ] UI / DX
- [ ] CI/CD / infra
## Linked Issue/PR
- Closes #12767
- Related #16321
## User-visible / Behavior Changes
- Before: heartbeat-only replies could appear in Telegram DM in this code path.
- After: heartbeat-only text is suppressed; mixed text keeps meaningful content; media payloads still deliver.
## Security Impact (required)
- New permissions/capabilities? (`No`)
- Secrets/tokens handling changed? (`No`)
- New/changed network calls? (`No`)
- Command/tool execution surface changed? (`No`)
- Data access scope changed? (`No`)
- If any `Yes`, explain risk + mitigation:
## Repro + Verification
### Environment
- OS: Ubuntu 24.04 (dev env)
- Runtime/container: Node v22.22.0, pnpm (corepack)
- Model/provider: N/A (unit-level validation)
- Integration/channel (if any): Telegram path (payload construction layer)
- Relevant config (redacted): default dev config, no special secrets
### Steps
1. Build payloads with assistant text `HEARTBEAT_OK` through embedded runner payload builder.
2. Build payloads with `HEARTBEAT_OK all clear`.
3. Build payloads with `HEARTBEAT_OK` + media directive.
### Expected
- Case 1 is dropped.
- Case 2 keeps only meaningful text.
- Case 3 keeps media deliverable.
### Actual
- Matches expected after fix.
## Evidence
- [x] Failing test/log before + passing after
- [x] Trace/log snippets
- [ ] Screenshot/recording
- [ ] Perf numbers (if relevant)
Evidence details:
- Added `src/agents/pi-embedded-runner/run/payloads.heartbeat-token.test.ts`
- drops pure `HEARTBEAT_OK`
- strips token and preserves real text
- preserves media payload when text is heartbeat-only
- Local commands run:
- `pnpm test src/agents/pi-embedded-runner/run/payloads.heartbeat-token.test.ts`
- `pnpm check`
## Human Verification (required)
What you personally verified (not just CI), and how:
- Verified scenarios: heartbeat-only text, heartbeat+content text, heartbeat+media
- Edge cases checked: token stripping preserves non-heartbeat text; media-only remains sendable
- What you did **not** verify: full end-to-end Telegram live delivery in this environment
## Compatibility / Migration
- Backward compatible? (`Yes`)
- Config/env changes? (`No`)
- Migration needed? (`No`)
- If yes, exact upgrade steps:
## Failure Recovery (if this breaks)
- How to disable/revert this change quickly: revert commit `8a53dda231bf9dbd9600c2f1dbe71ce6406b23a3`
- Files/config to restore: `src/agents/pi-embedded-runner/run/payloads.ts`
- Known bad symptoms reviewers should watch for: legitimate user text accidentally suppressed when token appears in normal sentence (covered by existing strip logic + tests)
## Risks and Mitigations
- Risk: overly aggressive token stripping might drop intended message text.
- Mitigation: rely on `stripHeartbeatToken(..., { mode: "message" })` semantics and regression tests for mixed-content and media cases.
---
AI-assisted: Yes (OpenAI Codex). I reviewed and validated the changes locally.
Testing degree: Light-to-moderate (targeted unit + project check).
lobster-biscuit
<!-- greptile_comment -->
<h3>Greptile Summary</h3>
Adds heartbeat token (`HEARTBEAT_OK`) suppression to the embedded payload builder to prevent control signals from leaking into user-facing Telegram DM replies. The fix uses the existing `stripHeartbeatToken` utility with `mode: "message"` to normalize text before payload construction, properly handling three cases: pure heartbeat tokens (dropped), mixed content (token stripped), and media-only payloads (preserved).
- Added heartbeat token stripping in `buildEmbeddedRunPayloads` mapping phase
- Comprehensive test coverage for all three scenarios
- Unrelated test isolation fix in `media.test.ts` using `mkdtemp` instead of hardcoded paths
<h3>Confidence Score: 5/5</h3>
- Safe to merge - targeted bug fix with comprehensive tests and no behavior changes to non-heartbeat messages
- The change is minimal and well-contained, reusing existing battle-tested `stripHeartbeatToken` utility. Test coverage validates all three edge cases. The media test fix is a legitimate improvement for test isolation. No architectural changes or risky refactoring.
- No files require special attention
<sub>Last reviewed commit: 498d6b0</sub>
<!-- greptile_other_comments_section -->
<sub>(3/5) Reply to the agent's comments like "Can you suggest a fix for this @greptileai?" or ask follow-up questions!</sub>
<!-- /greptile_comment -->
Most Similar PRs
#17371: fix(heartbeat): always strip HEARTBEAT_OK token from reply text
by BinHPdev · 2026-02-15
83.5%
#15575: fix(heartbeat): suppress prefixed HEARTBEAT_OK ack replies (#15505)
by TsekaLuk · 2026-02-13
82.3%
#19406: fix(heartbeat): filter error payloads from heartbeat reply selection
by namabile · 2026-02-17
82.2%
#19648: fix: suppress silent-reply partial tokens during streaming
by bradleypriest · 2026-02-18
81.9%
#21014: fix(cron): suppress main-session summary for HEARTBEAT_OK responses
by nickjlamb · 2026-02-19
81.0%
#19339: fix(heartbeat): skip isError payloads when resolving heartbeat reply
by aldoeliacim · 2026-02-17
80.0%
#21276: fix(telegram): stabilize partial finalization and MEDIA dedupe (AI-...
by HOYALIM · 2026-02-19
79.8%
#16373: fix: suppress leaked heartbeat poll prompts in reply delivery
by luisecab · 2026-02-14
79.6%
#19399: telegram: fix MEDIA false positives and partial final drop
by HOYALIM · 2026-02-17
79.5%
#23588: fix(auto-reply): suppress repetitive HEARTBEAT_OK loops
by mohandshamada · 2026-02-22
79.4%