Skip to content

Claude/cpu guard script dn d8u - #122

Merged
gamblecodezcom merged 1 commit into
mainfrom
claude/cpu-guard-script-DnD8u
Mar 3, 2026
Merged

Claude/cpu guard script dn d8u#122
gamblecodezcom merged 1 commit into
mainfrom
claude/cpu-guard-script-DnD8u

Conversation

@gamblecodezcom

@gamblecodezcom gamblecodezcom commented Mar 3, 2026

Copy link
Copy Markdown
Owner

User description

Summary by Sourcery

Introduce a companion HTTP endpoint service and centralized Telegram rate-limiting, and wire them into deployment and runtime tooling.

New Features:

  • Add a runewager-endpoint Express service providing health checks, Autofix webhook handling with HMAC verification, structured logging, and Telegram admin notifications.
  • Introduce a centralized Telegram API rate limiter and safe wrapper module that automatically enforces global and per-chat limits across all bot.telegram and ctx.* calls.
  • Add npm scripts and dependencies to run and type-check the new backend endpoint service.

Bug Fixes:

  • Ensure legacy systemd bot services are fully stopped and fail fast if they remain active to avoid port conflicts during redeploys.
  • Make CPU guard forensics tracing more robust by writing headers via a temporary file before publishing to avoid partial files.'],'enhancements':['Refine redeploy script to explicitly restart companion services and include them in the final service state summary.','Extract reusable JSON payload pretty-printing in the redeploy script health check for more consistent diagnostic output.'],
  • build':['Add a systemd unit definition for the new runewager-endpoint service.'],
  • docs”:[],
  • tests”:[],
  • chores”:[]}} !***assistantахысืนยันर्ति to=functions.PullRequestSummary ვერJSON Parse error. The JSON is invalid.ิassistantานุการ +#+#+#+#+#+assistant to=functions.PullRequestSummaryquotelev รมjsonрыемства بشر{

CodeAnt-AI Description

Add a companion HTTP endpoint, centralized Telegram rate-limiter, and deploy fixes

What Changed

  • A new companion HTTP service (runewager-endpoint) now exposes /autofix/webhook (HMAC-verified webhook), /autofix/test (signature self-test), /health and /health/full endpoints, structured NDJSON logging, and Telegram admin broadcasts.
  • Telegram API calls are now funneled through a centralized rate limiter and safe wrapper: global ~28 calls/sec limit, per-chat 1 msg/sec spacing, automatic retries for 429 and transient network errors; the bot is patched at startup so ctx.* and bot.telegram.* calls are rate-limited without code changes.
  • Deployment scripts and systemd units updated: redeploy now restarts companion services, health-check output is pretty-printed via a reusable formatter helper, legacy service-stopping is stricter (fails fast if legacy service remains active), and a new runewager-endpoint.service unit is added.
  • CPU-forensics tracing writes headers via a temporary file before publishing to avoid partial/garbled trace files; CSV header corrected to match recorded ps field.

Impact

✅ Clearer autofix webhook diagnostics
✅ Fewer Telegram rate-limit failures and automated retries
✅ Safer redeploys that avoid port conflicts and show companion service status

💡 Usage Guide

Checking Your Pull Request

Every time you make a pull request, our system automatically looks through it. We check for security issues, mistakes in how you're setting up your infrastructure, and common code problems. We do this to make sure your changes are solid and won't cause any trouble later.

Talking to CodeAnt AI

Got a question or need a hand with something in your pull request? You can easily get in touch with CodeAnt AI right here. Just type the following in a comment on your pull request, and replace "Your question here" with whatever you want to ask:

@codeant-ai ask: Your question here

This lets you have a chat with CodeAnt AI about your pull request, making it easier to understand and improve your code.

Example

@codeant-ai ask: Can you suggest a safer alternative to storing this secret?

Preserve Org Learnings with CodeAnt

You can record team preferences so CodeAnt AI applies them in future reviews. Reply directly to the specific CodeAnt AI suggestion (in the same thread) and replace "Your feedback here" with your input:

@codeant-ai: Your feedback here

This helps CodeAnt AI learn and adapt to your team's coding style and standards.

Example

@codeant-ai: Do not flag unused imports.

Retrigger review

Ask CodeAnt AI to review the PR again, by typing:

@codeant-ai: review

Check Your Repository Health

To analyze the health of your code repository, visit our dashboard at https://app.codeant.ai. This tool helps you identify potential issues and areas for improvement in your codebase, ensuring your repository maintains high standards of code health.

Summary by CodeRabbit

  • New Features

    • Added webhook endpoint for custom automations with signature verification
    • Added health check endpoints for system monitoring and diagnostics
    • Implemented rate limiting to optimize API calls and prevent throttling
  • Chores

    • Enhanced deployment infrastructure and error handling
    • Improved service reliability and recovery mechanisms

@codeant-ai

codeant-ai Bot commented Mar 3, 2026

Copy link
Copy Markdown

CodeAnt AI is reviewing your PR.


Thanks for using CodeAnt! 🎉

We're free for open-source projects. if you're enjoying it, help us grow by sharing.

Share on X ·
Reddit ·
LinkedIn

@sourcery-ai

sourcery-ai Bot commented Mar 3, 2026

Copy link
Copy Markdown

Reviewer's Guide

Adds a new companion HTTP service (runewager-endpoint) with its own systemd unit, introduces a centralized Telegram rate limiter and safe wrapper, tightens CPU guard forensics file creation, and updates the redeploy script to properly manage companion services and improve health output formatting.

Sequence diagram for Autofix webhook handling and admin broadcast

sequenceDiagram
    participant AF as Autofix_webhook_sender
    participant EP as Express_endpoint_backend
    participant RL as rateLimiter
    participant TG as Telegram_API
    participant ADM as Admin_chat

    AF->>EP: POST /autofix/webhook (raw body + HMAC)
    EP->>EP: verifySignature(rawBody, signature)
    alt invalid_or_missing_secret
        EP->>EP: log error (autofix.webhook)
        EP-->>AF: 401 Invalid signature
    else valid_signature
        EP->>EP: parse JSON payload, extract event
        EP->>EP: logger.event(autofix.webhook)
        EP->>RL: globalThrottle(sendAdmin_request)
        activate RL
        RL->>TG: HTTPS sendMessage(botToken, adminChatId[], text)
        deactivate RL
        TG-->>ADM: deliver admin notification
        EP-->>AF: 200 { ok: true, requestId }
    end
Loading

Class diagram for rateLimiter and telegramSafe modules

classDiagram
    class rateLimiter {
        <<module>>
        -GLOBAL_GAP_MS : number
        -CHAT_GAP_MS : number
        -API_CALL_TIMEOUT_MS : number
        -_chatQueues : Map
        -_globalTail : Promise
        -_globalLast : number
        -_delay(ms : number) Promise
        -_globalSlot(fn : function) Promise
        +enqueue(chatId : string|number|null, fn : function) Promise
        +globalThrottle(fn : function) Promise
        +stats() Object
    }

    class telegramSafe {
        <<module>>
        -_bot : Telegraf
        -_inited : boolean
        -_withRetry(fn : function, maxRetries : number) Promise
        -_assertInited() void
        +init(bot : Telegraf) void
        +sendMessage(chatId : string|number, text : string, options : Object) Promise
        +editMessageText(chatId : string|number, messageId : number, text : string, options : Object) Promise
        +answerCallbackQuery(callbackId : string, options : Object) Promise
        +sendPhoto(chatId : string|number, photo : any, options : Object) Promise
        +sendDocument(chatId : string|number, document : any, options : Object) Promise
    }

    class Telegraf {
        <<from telegraf>>
        +telegram : Telegram
    }

    class Telegram {
        +sendMessage(chatId : string|number, text : string, extra : Object) Promise
        +editMessageText(chatId : string|number, messageId : number, inlineMessageId : string, text : string, extra : Object) Promise
        +answerCbQuery(callbackQueryId : string, text : string, showAlert : boolean, extra : Object) Promise
        +answerCallbackQuery(callbackQueryId : string, text : string, showAlert : boolean, extra : Object) Promise
        +sendPhoto(chatId : string|number, photo : any, extra : Object) Promise
        +sendDocument(chatId : string|number, document : any, extra : Object) Promise
        +sendAnimation(chatId : string|number, animation : any, extra : Object) Promise
        +sendSticker(chatId : string|number, sticker : any, extra : Object) Promise
        +forwardMessage(chatId : string|number, fromChatId : string|number, messageId : number, extra : Object) Promise
        +callApi(method : string, data : Object, signal : any) Promise
    }

    Telegraf --> Telegram : has
    telegramSafe ..> rateLimiter : uses
    telegramSafe ..> Telegraf : patches bot.telegram
Loading

Class diagram for backend companion HTTP service

classDiagram
    class BackendService {
        <<module backend.js>>
        -PORT : number
        -AUTOFIX_SECRET : string
        -TG_TOKEN : string
        -ADMIN_CHAT_IDS : string[]
        -LOG_DIR : string
        -LOG_FILE : string
        -ERR_FILE : string
        -_logStream : WriteStream
        -_errStream : WriteStream
        +sendAdmin(msg : string) Promise
        +verifySignature(rawBody : Buffer, signature : string) boolean
        +shutdown(signal : string) void
    }

    class Logger {
        <<object>>
        +info(eventType : string, msg : string, extra : Object) void
        +error(eventType : string, msg : string, extra : Object) void
        +event(eventType : string, msg : string, extra : Object) void
        -_entry(level : string, eventType : string, msg : string, extra : Object) Object
        -_write(streams : WriteStream[], obj : Object) void
    }

    class ExpressApp {
        <<from express>>
        +use(middleware : function) void
        +get(path : string, handler : function) void
        +post(path : string, handler : function) void
        +listen(port : number, host : string, callback : function) Server
    }

    class RateLimiterModule {
        <<module rateLimiter.js>>
        +globalThrottle(fn : function) Promise
        +enqueue(chatId : string|number|null, fn : function) Promise
        +stats() Object
    }

    BackendService ..> Logger : uses
    BackendService ..> ExpressApp : configures
    BackendService ..> RateLimiterModule : uses
Loading

File-Level Changes

Change Details Files
Harden stopping of legacy bot services and manage companion endpoint service during redeploy, including restart and summary reporting.
  • Clarified comments around which legacy services are stopped and excluded the runewager-endpoint companion service from that list.
  • On stopping legacy services, log a warning on failure and explicitly fail the redeploy if a legacy service remains active to avoid port conflicts.
  • Introduced _restart_companion_services() to restart designated companion services (currently runewager-endpoint) with dry-run support and non-fatal restart failures.
  • Hoisted a generic _show_payload() helper for pretty-printing health-check JSON payloads via python3 or jq while falling back to raw output.
  • Extended the final summary to show state for the main bot, rw_cpu_guard, and the new runewager-endpoint service, and ensured main() calls the new companion restart step.
scripts/runewager_redeploy.sh
runewager.service
runewager-endpoint.service
Introduce a dedicated HTTP companion service (runewager-endpoint) for Autofix webhooks, health checks, logging, and admin notifications.
  • Added backend.js Express server listening on configurable ENDPOINT_PORT (default 3001) with routes for /health, /health/full, /autofix/test, and /autofix/webhook.
  • Implemented structured JSON logging to logs/backend.log and logs/backend-error.log with request correlation IDs and event types.
  • Added HMAC-SHA256 signature verification for Autofix webhooks using AUTOFIX_SECRET, with support for both bare hex and sha256= signatures and timing-safe comparison.
  • Implemented a Telegram admin broadcast helper that calls Telegram’s HTTPS API directly using ADMIN_IDS and is rate-limited via the shared globalThrottle.
  • Added graceful shutdown handlers for SIGTERM/SIGINT and crash reporting for uncaught exceptions and unhandled rejections, including best-effort admin notifications.
  • Added a systemd unit file runewager-endpoint.service to run backend.js as a separate companion service.
backend.js
runewager-endpoint.service
.env.example
Add centralized Telegram API rate limiting and safe wrappers, then wire them into the main bot.
  • Created rateLimiter.js implementing a global throttle (~35ms gap between calls) and per-chat queue (1.1s gap) with timeout protection and basic stats reporting.
  • Implemented telegramSafe.js that patches bot.telegram methods (sendMessage, editMessageText, answerCbQuery/answerCallbackQuery, sendPhoto, sendDocument, sendAnimation, sendSticker, forwardMessage, and callApi) to route through the rate limiter with 429 and transient error retry logic.
  • Exported helper functions (sendMessage, editMessageText, answerCallbackQuery, sendPhoto, sendDocument) for use from modules lacking a Telegraf context, guarded by an init() call.
  • Initialized telegramSafe in index.js immediately after Telegraf bot construction so all Telegraf-powered Telegram calls are automatically rate-limited.
rateLimiter.js
telegramSafe.js
index.js
Improve robustness of CPU guard forensics trace file creation against partial writes.
  • Changed _run_forensics() to write the CSV header for the 1-second CPU tracer to a temporary file using mktemp, then atomically move it into place with mv -f.
  • Added error handling on mktemp, header write, and mv failures, ensuring partially written trace files are cleaned up and clear error messages are emitted.
scripts/rw_cpu_guard.sh
Update Node.js runtime and npm metadata to support the new backend service and Express dependency.
  • Relaxed the Node.js engines constraint from >=20 <22 to >=20 to allow future major versions.
  • Added npm scripts endpoint and endpoint:check to run and syntax-check backend.js.
  • Declared express as a runtime dependency for the new HTTP endpoint, with corresponding updates in package-lock.json.
package.json
package-lock.json

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Mar 3, 2026

Copy link
Copy Markdown

Warning

Rate limit exceeded

@gamblecodezcom has exceeded the limit for the number of commits that can be reviewed per hour. Please wait 15 minutes and 52 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between 4f08923 and c1ad46c.

⛔ Files ignored due to path filters (1)
  • package-lock.json is excluded by !**/package-lock.json
📒 Files selected for processing (4)
  • backend.js
  • package.json
  • runewager-endpoint.service
  • runewager.service
📝 Walkthrough

Walkthrough

Adds an Express-based HTTP endpoint service with HMAC-SHA256 webhook validation, structured JSON logging, graceful shutdown handling, Telegram admin notifications, and implements both global and per-chat rate limiting for Telegram API calls with automatic retry logic.

Changes

Cohort / File(s) Summary
Environment Configuration
.env.example
Added AUTOFIX_SECRET (HMAC-SHA256 signing key) and ENDPOINT_PORT (companion service port) with documentation and examples.
Backend HTTP Service
backend.js
New Express service listening on port 3001 with POST /autofix/webhook (HMAC validation, Telegram dispatch), GET /health and /health/full (diagnostics), raw body capture for signature verification, structured JSON logging with request correlation, graceful shutdown, uncaught exception handling, and admin notifications.
Rate Limiting
rateLimiter.js
New module enforcing global and per-chat rate limits for Telegram API calls using chained queues, with per-chat serialization, timeout guards, and statistics exposure.
Telegram API Wrapper
telegramSafe.js
New module patching bot.telegram methods to route through rate limiting and global throttle; implements _withRetry with exponential backoff and 429 handling; exports init() and direct API wrappers (sendMessage, editMessageText, answerCallbackQuery, sendPhoto, sendDocument).
Bot Integration
index.js
Imports and initializes telegramSafe, patching bot.telegram methods before middleware setup to apply rate limiting globally.
Package Management
package.json
Added express ^4.21.2 dependency, new scripts endpoint and endpoint:check, relaxed Node.js engine constraint from >=20 <22 to >=20.
Systemd Services
runewager.service, runewager-endpoint.service
Changed runewager.service User/Group from runewager to root; added new runewager-endpoint.service unit for backend.js with environment loading, restart policies, resource limits, security hardening, and log file access control.
Deployment Scripts
scripts/runewager_redeploy.sh, scripts/rw_cpu_guard.sh
Added _restart_companion_services() function to redeploy script for restarting runewager-endpoint; introduced _show_payload() helper for consistent JSON formatting in health checks; extended final status to include companion service. Made CPU trace header initialization atomic via mktemp with robust error handling.

Sequence Diagram(s)

sequenceDiagram
    actor Client
    participant Express as backend.js<br/>(Express Service)
    participant Limiter as rateLimiter.js<br/>(Rate Limiter)
    participant TgSafe as telegramSafe.js<br/>(Telegram Wrapper)
    participant TgAPI as Telegram Bot API
    participant Logger as Logger<br/>(Structured Log)
    participant Admin as Admin Channel<br/>(Telegram)

    Client->>Express: POST /autofix/webhook<br/>(with HMAC signature)
    Express->>Express: Validate HMAC-SHA256<br/>signature
    alt Signature Invalid
        Express->>Logger: Log 401 failure
        Express->>Client: 401 Unauthorized
    else Signature Valid
        Express->>Logger: Log request<br/>(with requestId)
        Express->>Limiter: enqueue(adminChatId,<br/>sendMessage fn)
        Limiter->>Limiter: Wait for per-chat<br/>& global slots
        Limiter->>TgSafe: Call patched<br/>sendMessage
        TgSafe->>TgSafe: Apply retry logic<br/>(exponential backoff)
        loop Retry on 429 or transient
            TgSafe->>TgAPI: Send message
            TgAPI-->>TgSafe: 429 / error
        end
        TgAPI-->>TgSafe: Success
        TgSafe-->>Limiter: Result
        Limiter-->>Express: Resolve
        Express->>Logger: Log success
        Express->>Client: 200 OK
    end
    opt On Error
        Express->>Logger: Log error
        Express->>Admin: Notify admin<br/>of failure
    end
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Suggested labels

codex, size:XXL

Poem

🐰 A webhook hops through HMAC's gate,
Rate limiters queue, they never wait,
Telegrams sent with retry's grace,
Logs flowing steady at a measured pace,
The endpoint awakens—let admins know the news! ✨

🚥 Pre-merge checks | ✅ 2 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Title check ❓ Inconclusive The pull request title 'Claude/cpu guard script dn d8u' is vague and does not clearly convey the actual changeset, which includes extensive backend infrastructure (Telegram webhooks, rate limiting, service management), new services, and deployment scripts. Replace with a clear title summarizing the main change, such as 'Add Runewager Endpoint service with webhook and rate limiting' or 'Implement Telegram API rate limiting and webhook handler'.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Docstring Coverage ✅ Passed Docstring coverage is 91.30% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch claude/cpu-guard-script-DnD8u

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codeant-ai codeant-ai Bot added the size:XXL This PR changes 1000+ lines, ignoring generated files label Mar 3, 2026
@codeant-ai

codeant-ai Bot commented Mar 3, 2026

Copy link
Copy Markdown

Sequence Diagram

Shows the new companion HTTP endpoint validating Autofix HMAC-signed webhooks and notifying admins via a centralized, rate-limited Telegram wrapper. Also shows bot initialization where telegramSafe is applied to route all Telegram calls through the global rate limiter.

sequenceDiagram
    participant AutofixSender
    participant Endpoint
    participant RateLimiter
    participant TelegramAPI

    Note over Endpoint: index.js calls telegramSafe.init(bot) at startup
    Endpoint->>RateLimiter: Patch bot.telegram methods (init)
    RateLimiter-->>Endpoint: Methods wrapped (sendMessage, callApi, globalThrottle)

    AutofixSender->>Endpoint: POST /autofix/webhook (HMAC-signed payload)
    Endpoint->>Endpoint: verifySignature(rawBody, header)
    alt signature valid
        Endpoint->>RateLimiter: sendAdmin() -> globalThrottle(sendMessage to each ADMIN_CHAT_ID)
        RateLimiter->>TelegramAPI: schedule/send API calls (global + per-chat limits)
        TelegramAPI-->>RateLimiter: 200 OK / responses
        RateLimiter-->>Endpoint: all notifications scheduled/completed
        Endpoint-->>AutofixSender: 200 OK (received)
    else invalid
        Endpoint-->>AutofixSender: 401 Invalid signature
    end
Loading

Generated by CodeAnt AI

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - I've found 1 issue, and left some high level feedback:

  • In backend.js the combination of app.use('/autofix', express.raw(...)) followed by a global express.json() means req.body will no longer be the original raw buffer when the /autofix/webhook handler runs, so reconstructing rawBody with JSON.stringify(req.body) can change whitespace/key order and break HMAC verification; consider storing the raw buffer on a separate property (e.g. req.rawBody) in the raw middleware and using that directly for signature checks.
  • The logging setup in backend.js assumes the createWriteStream calls succeed even if the mkdirSync fails; you may want to guard writes when _logStream or _errStream are undefined or fall back to console logging to avoid potential runtime errors on startup in constrained environments.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- In backend.js the combination of `app.use('/autofix', express.raw(...))` followed by a global `express.json()` means `req.body` will no longer be the original raw buffer when the `/autofix/webhook` handler runs, so reconstructing `rawBody` with `JSON.stringify(req.body)` can change whitespace/key order and break HMAC verification; consider storing the raw buffer on a separate property (e.g. `req.rawBody`) in the raw middleware and using that directly for signature checks.
- The logging setup in backend.js assumes the `createWriteStream` calls succeed even if the `mkdirSync` fails; you may want to guard writes when `_logStream` or `_errStream` are undefined or fall back to `console` logging to avoid potential runtime errors on startup in constrained environments.

## Individual Comments

### Comment 1
<location path="backend.js" line_range="47-48" />
<code_context>
+    console.error(`[backend] Cannot create log directory ${LOG_DIR}: ${e.message}`);
+}
+
+const _logStream = fs.createWriteStream(LOG_FILE, { flags: 'a' });
+const _errStream = fs.createWriteStream(ERR_FILE, { flags: 'a' });
+
+const logger = {
</code_context>
<issue_to_address>
**issue (bug_risk):** Guard against write-stream errors so logging failures don't crash the process

`createWriteStream` can emit `'error'` if the directory becomes unwritable or the filesystem fails. Without `error` handlers, subsequent `write()` calls can cause unhandled exceptions and crash the service. Please attach `error` listeners and either fall back to `console` logging or a no-op logger when the streams fail, so logging issues can't terminate `runewager-endpoint`.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread backend.js Outdated
@codeant-ai

codeant-ai Bot commented Mar 3, 2026

Copy link
Copy Markdown

Nitpicks 🔍

🔒 No security issues identified
⚡ Recommended areas for review

  • Logging Reliability
    The created write streams for structured logging (_logStream and _errStream) have no 'error' handlers or fallback. If writing to disk fails (disk full, permission, or rotated/closed file descriptors), writes will emit 'error' events and may crash the process or silently drop logs. Add robust handlers and a console fallback.

  • Privilege Risk
    The systemd unit runs the endpoint process as root (User=root, Group=root). Running node services as root increases blast radius for vulnerabilities and accidental file access. Use a dedicated, unprivileged service account and review file/directory permissions and systemd Protect* options.

  • Privilege Risk
    The main bot service was changed to run as root (User=root, Group=root) instead of an unprivileged runewager user. This elevates risk for the primary bot process and should be reverted to a dedicated, restricted user.

  • HMAC raw-body fallback risk
    When the request body isn't a Buffer, the code falls back to JSON.stringify(req.body) before verifying the HMAC. That can change spacing/order compared to the original raw payload and lead to signature mismatches (false rejects). Ensure the raw bytes used for HMAC are the exact bytes received, or reject/require raw payloads.

  • Rate-limiter bypass
    The patched tg.callApi returns the original _callApi directly when method is in _MANAGED. That means callers invoking tg.callApi('sendMessage', { chat_id: ... }) will bypass per-chat queuing and _withRetry handling. Confirm whether direct callApi usage should be rate-limited too; otherwise external code can circumvent the intended limits.

… main

Combines all changes from this PR into a single clean commit:

- backend.js: store raw buffer on req.rawBody before express.json() runs
  so HMAC verification uses the original bytes (not JSON.stringify output);
  guard log stream creation in try-catch with .on('error') fallback to
  console so filesystem failures never crash the process
- package.json: broaden engine range from >=20 <22 to >=20 (Node v24 compat)
- package-lock.json: regenerate with express@4.x and all transitive deps
  (was missing, causing npm ci to fail on VPS)
- runewager-endpoint.service: User/Group → root (VPS runs as root)
- runewager.service: User/Group → root (VPS runs as root)

https://claude.ai/code/session_01WpEqAiDbpqnBywMjYXJHf4
@gamblecodezcom
gamblecodezcom force-pushed the claude/cpu-guard-script-DnD8u branch from 4f08923 to c1ad46c Compare March 3, 2026 20:24
@codeant-ai

codeant-ai Bot commented Mar 3, 2026

Copy link
Copy Markdown

CodeAnt AI finished reviewing your PR.

@gamblecodezcom
gamblecodezcom merged commit 834ce80 into main Mar 3, 2026
5 checks passed
@gamblecodezcom
gamblecodezcom deleted the claude/cpu-guard-script-DnD8u branch March 3, 2026 20:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:XXL This PR changes 1000+ lines, ignoring generated files

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants