Skip to content

fix(autonomous): deliver escalations to user (AUDIT-H2)#263

Merged
xlabtg merged 4 commits intoxlabtg:mainfrom
konard:issue-262-ca6c791caa77
Apr 22, 2026
Merged

fix(autonomous): deliver escalations to user (AUDIT-H2)#263
xlabtg merged 4 commits intoxlabtg:mainfrom
konard:issue-262-ca6c791caa77

Conversation

@konard
Copy link
Copy Markdown

@konard konard commented Apr 22, 2026

Summary

Route autonomous-task escalations through real user-facing channels instead of the logger only. Closes #262 (AUDIT-H2).

src/autonomous/integration.ts notify() now:

  1. Sends a Telegram DM to every admin in config.telegram.admin_ids via deps.bridge.sendMessage.
  2. Records the escalation as a warning entry in the existing notifications table, and emits update + escalation events on notificationBus so the WebUI SSE stream (/api/notifications/stream) raises a real-time badge.
  3. Keeps log.warn as the first action so the log trail survives even when every side channel is down.

Each channel is wrapped in its own try/catch, so a Telegram outage cannot suppress the WebUI notification and vice versa.

How to reproduce

Before this PR, a policy-triggered escalation (e.g. a planned wallet:send above the confirmation threshold) paused the task but only produced a log line — the user had to notice the pause by polling the UI. The new integration tests exercise that exact path and assert that the mock bridge + notificationBus both see the event.

Test plan

  • npm test — 2936 tests across 139 files pass
  • npm run lint
  • npm run typecheck (after npm run build:sdk)
  • npm run -- prettier --check on the modified files
  • New regression tests in src/autonomous/__tests__/integration.test.ts:
    • notify() sends a Telegram message to every configured admin via bridge
    • notify() skips Telegram delivery when no admin_ids are configured
    • notify() emits an escalation event on notificationBus for WebUI
    • notify() records an in-app notification so the WebUI badge updates
    • notify() still logs and emits a bus event when bridge.sendMessage throws
    • policy-triggered escalation reaches bridge.sendMessage end-to-end (drives AutonomousLoop through the integrated deps with a wallet:send over the 0.5 TON confirmation threshold and asserts the mock bridge received the DM)

Acceptance criteria (from issue)

  • Escalation is sent to Telegram via bridge to all admins
  • Escalation is emitted on notificationBus for WebUI
  • Fallback to log.warn without crashing when bridge/bus fails (per-channel try/catch)
  • Unit test: notify calls bridge.sendMessage with the correct chatId
  • Unit test: notify is resilient to a bridge error and still logs
  • Integration test: policy-escalation → message delivered to mock bridge

konard added 2 commits April 22, 2026 19:59
Adding .gitkeep for PR creation (default mode).
This file will be removed when the task is complete.

Issue: xlabtg#262
Route policy-triggered escalations through the Telegram bridge and the
in-app notificationBus instead of only writing to the logger. When the
autonomous loop pauses a task for human confirmation, every configured
admin now receives a DM via deps.bridge.sendMessage, an entry is added
to the notifications table, and WebUI SSE clients see the unread-count
badge update in real time. Each channel is guarded independently so a
single transport failure never suppresses the others and log.warn stays
as the last-resort fallback.

Closes xlabtg#262
@konard konard changed the title [WIP] audit-h2-escalations-never-reach-user fix(autonomous): deliver escalations to user (AUDIT-H2) Apr 22, 2026
@konard konard marked this pull request as ready for review April 22, 2026 20:08
@konard
Copy link
Copy Markdown
Author

konard commented Apr 22, 2026

Solution summary

PR is ready and mergeable. Summary:

  • PR: fix(autonomous): deliver escalations to user (AUDIT-H2) #263
  • Fix: src/autonomous/integration.ts:110-143notify() now DMs every admin via deps.bridge.sendMessage, records a warning row in the notifications table, and emits update/escalation on notificationBus for WebUI SSE. Each channel is try/catch-guarded; log.warn remains as the first-line fallback.
  • Tests: added 6 regression tests in src/autonomous/__tests__/integration.test.ts (unit + end-to-end through AutonomousLoop with policy-triggered escalation). Full suite: 2936 tests pass, lint clean, typecheck clean.
  • CHANGELOG.md: added Unreleased entry under Fixed.

This summary was automatically extracted from the AI working session output.

@konard
Copy link
Copy Markdown
Author

konard commented Apr 22, 2026

🤖 Solution Draft Log

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost: $3.328022

📊 Context and tokens usage:

  • 102.2K / 1M (10%) input tokens, 19.6K / 128K (15%) output tokens

Total: (98.2K + 4.4M cached) input tokens, 19.6K output tokens, $3.328022 cost

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Model: Claude Opus 4.7 (claude-opus-4-7)

📎 Log file uploaded as Gist (1663KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

@konard
Copy link
Copy Markdown
Author

konard commented Apr 22, 2026

🔄 Auto-restart triggered (iteration 1)

Reason: Merge conflicts detected

Starting new session to address the issues.


Auto-restart-until-mergeable mode is active. Will continue until PR becomes mergeable.

konard added 2 commits April 22, 2026 20:15
Resolves .gitkeep timestamp conflict and updates the AUDIT-H2
integration test to use the new real tool name (ton_send) that
AUDIT-C1 introduced in DEFAULT_POLICY_CONFIG.restrictedTools.
Pulls the latest AUDIT fixes (policy engine tool-name corrections,
autonomous loop abort safety, checkpoint retention, webui auth token
redaction). Resolves the .gitkeep timestamp conflict; no other
conflicts. Integration test already updated to use the real tool
name `ton_send` from DEFAULT_POLICY_CONFIG.
@xlabtg xlabtg merged commit b5da40c into xlabtg:main Apr 22, 2026
@konard
Copy link
Copy Markdown
Author

konard commented Apr 22, 2026

🔄 Auto-restart-until-mergeable Log (iteration 1)

This log file contains the complete execution trace of the AI solution draft process.

💰 Cost: $2.892774

📊 Context and tokens usage:

  • 76.2K / 1M (8%) input tokens, 15.4K / 128K (12%) output tokens

Total: (76.1K + 4.1M cached) input tokens, 15.4K output tokens, $2.892774 cost

🤖 Models used:

  • Tool: Anthropic Claude Code
  • Requested: opus
  • Model: Claude Opus 4.7 (claude-opus-4-7)

📎 Log file uploaded as Gist (3287KB)


Now working session is ended, feel free to review and add any feedback on the solution draft.

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.

audit-h2-escalations-never-reach-user

2 participants