Skip to content

fix(notify): bound hook input and provider payload sizes (#618) - #666

Merged
solomonneas merged 3 commits into
mainfrom
fix/618-bound-hook-input
Aug 2, 2026
Merged

fix(notify): bound hook input and provider payload sizes (#618)#666
solomonneas merged 3 commits into
mainfrom
fix/618-bound-hook-input

Conversation

@solomonneas

@solomonneas solomonneas commented Aug 1, 2026

Copy link
Copy Markdown
Collaborator

Summary

  • Hook and stdin reads go through adapter.ReadBounded (256 KiB) so allocation cannot grow without bound.
  • Discord, Telegram, and Signal adapters truncate or refuse payloads against documented ceilings.
  • Oversized sends that cannot preserve the message contract fail with DeliveryError cause payload_limit; stderr stays on SafeError (no credentials or raw provider bodies).

Acceptance criteria → tests

Criterion Test
Input immediately below, at, and above the hook limit TestReadBounded_BelowLimit, TestReadBounded_AtLimit, TestReadBounded_AboveLimit, TestAutoDetect_AboveLimit, TestRun_OversizedStdinRejected
Each provider adapter has payload-limit tests TestDiscord_Send_TruncatesDescriptionToLimit, TestTelegram_Send_TruncatesToTextMax, TestTelegram_Send_PayloadLimitWhenTitleAloneExceeds, TestSignal_Send_TruncatesToMessageMax
Partial delivery visible in exit status and diagnostics TestRun_PartialFailurePayloadLimitVisible
Truncated diagnostics omit credentials / raw provider responses TestRun_PartialFailurePayloadLimitVisible, TestTelegram_Send_PayloadLimitWhenTitleAloneExceeds, TestDiscord_Send_PayloadLimitErrorHasNoSecrets

Test plan

  • brigade work verify run --target . --command "./scripts/verify" --capture brigade-work
    • receipt: 20260801-215514-work-verify-2a81e8
  • brigade work verify run --target ./stations/notify --command "go test ./..." --capture brigade-work
    • receipt: 20260801-215512-work-verify-0d3674

Closes #618

Made with Cursor

Summary by CodeRabbit

  • New Features

    • Added input-size protection for notification commands, rejecting oversized payloads before processing.
    • Added provider-specific message limits with safe, UTF-8-aware truncation for Discord, Telegram, and Signal.
    • Added clear payload-limit error reporting without exposing sensitive content.
  • Bug Fixes

    • Prevented unbounded input reads and oversized messages from being sent.
    • Improved handling of partial delivery failures when a provider rejects an oversized payload.

Cap stdin/hook reads at 256 KiB and truncate or refuse Discord, Telegram,
and Signal payloads against documented ceilings so oversized events fail
with a bounded payload_limit diagnostic instead of silent non-delivery.

Closes #618

Co-authored-by: Cursor <cursoragent@cursor.com>
@coderabbitai

coderabbitai Bot commented Aug 1, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Agent Notify now bounds hook and positional input to 256 KiB. Discord, Telegram, and Signal payloads are fitted to provider limits. Oversized content returns sanitized payload_limit errors, with tests covering boundaries and partial delivery.

Changes

Notification size enforcement

Layer / File(s) Summary
Bounded hook input
stations/notify/internal/adapter/..., stations/notify/cmd/agent-notify/main.go, stations/notify/cmd/agent-notify/main_test.go
Input readers use the 256 KiB bound. Positional input and oversized stdin are rejected before conversion or provider calls.
Provider limits and delivery errors
stations/notify/internal/channels/limits.go, stations/notify/internal/channels/errors.go, stations/notify/internal/channels/limits_test.go
Provider limits, UTF-8-safe truncation, and sanitized payload_limit errors are defined and tested.
Provider payload fitting
stations/notify/internal/channels/discord.go, stations/notify/internal/channels/telegram.go, stations/notify/internal/channels/signal.go, stations/notify/cmd/agent-notify/main_test.go
Discord embeds, Telegram text, and Signal messages are fitted before transport. Tests cover provider requests and partial delivery.

Estimated code review effort: 4 (Complex) | ~45 minutes

Possibly related issues

  • escoffier-labs/agent-notify#12 — Requests bounded hook input and provider-specific payload validation across the same notification paths.

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 29.17% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main changes: bounded hook input and provider payload sizes.
Linked Issues check ✅ Passed The changes address all coding objectives in issue #618, including bounded input, provider limits, failure reporting, tests, and diagnostic redaction.
Out of Scope Changes check ✅ Passed All code changes support issue #618 objectives and no unrelated scope is evident.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/618-bound-hook-input

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 golangci-lint (2.12.2)

level=error msg="[linters_context] typechecking error: pattern ./...: directory prefix . does not contain main module or its selected dependencies"


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.

@solomonneas solomonneas self-assigned this Aug 1, 2026
@solomonneas solomonneas added the coderabbit-review Request one CodeRabbit review after CI is green label Aug 1, 2026 — with ChatGPT Codex Connector

@coderabbitai coderabbitai 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.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@stations/notify/cmd/agent-notify/main_test.go`:
- Around line 869-873: Update adapterMaxInputBytes in the CLI test helper to
return the exported adapter.MaxInputBytes constant instead of duplicating the
numeric limit, using the existing adapter package import and preserving
TestRun_OversizedStdinRejected’s behavior.

In `@stations/notify/internal/channels/limits_test.go`:
- Around line 64-101: Replace the non-executing fixture and direct
payloadLimitError call in TestDiscord_Send_PayloadLimitErrorHasNoSecrets with a
genuinely oversized message, such as a large Body combined with maximum title,
footer, and tags, that drives fitDiscordEmbed beyond DiscordEmbedTotalMax.
Invoke d.Send with a context and msg using the secret webhook URL, assert it
returns the payload-limit error, then run SafeError on that returned error and
verify it contains payload_limit without exposing the webhook URL or HTTP
scheme. Remove the unconditional skip and unused-variable workarounds.

In `@stations/notify/internal/channels/telegram.go`:
- Around line 100-134: Fix the binary-search direction in fitTelegramText: when
truncateRunes returns !ok for mid, increase the lower bound with lo = mid + 1
instead of decreasing hi, since larger budgets may succeed. Add a regression
test using a short body and near-limit title/tag overhead where truncation is
required but feasible, verifying fitTelegramText returns a valid payload rather
than payloadLimitError.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: escoffier-labs/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: df501fc9-08c9-48a0-877d-0f006a655e3a

📥 Commits

Reviewing files that changed from the base of the PR and between 4f89436 and 1dffd45.

📒 Files selected for processing (14)
  • stations/notify/cmd/agent-notify/main.go
  • stations/notify/cmd/agent-notify/main_test.go
  • stations/notify/internal/adapter/adapter.go
  • stations/notify/internal/adapter/bound.go
  • stations/notify/internal/adapter/bound_test.go
  • stations/notify/internal/adapter/claude_code_notification.go
  • stations/notify/internal/adapter/claude_code_stop.go
  • stations/notify/internal/adapter/codex_notify.go
  • stations/notify/internal/channels/discord.go
  • stations/notify/internal/channels/errors.go
  • stations/notify/internal/channels/limits.go
  • stations/notify/internal/channels/limits_test.go
  • stations/notify/internal/channels/signal.go
  • stations/notify/internal/channels/telegram.go

Comment thread stations/notify/cmd/agent-notify/main_test.go Outdated
Comment thread stations/notify/internal/channels/limits_test.go Outdated
Comment thread stations/notify/internal/channels/telegram.go
@solomonneas

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@solomonneas

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Aug 2, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai 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.

🧹 Nitpick comments (1)
stations/notify/cmd/agent-notify/main.go (1)

306-308: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Validate positional size before joining arguments.

strings.Join and []byte(joined) allocate the complete custom payload before CheckSize rejects it. Sum argument byte lengths and separators before strings.Join. Return adapter.ErrInputTooLarge when the total exceeds adapter.MaxInputBytes.

Proposed change
-			joined := strings.Join(posArgs, " ")
-			if err := adapter.CheckSize([]byte(joined)); err != nil {
-				return canonical.Message{}, err
+			size := len(posArgs) - 1
+			for _, arg := range posArgs {
+				if len(arg) > adapter.MaxInputBytes-size {
+					return canonical.Message{}, adapter.ErrInputTooLarge
+				}
+				size += len(arg)
 			}
+			joined := strings.Join(posArgs, " ")
 			return adapter.FromString(joined), nil
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@stations/notify/cmd/agent-notify/main.go` around lines 306 - 308, Update the
positional-argument handling around adapter.CheckSize to calculate the total
UTF-8 byte length of posArgs plus one space separator between adjacent arguments
before calling strings.Join. If the total exceeds adapter.MaxInputBytes, return
adapter.ErrInputTooLarge without constructing the joined payload; otherwise
preserve the existing join and CheckSize flow.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Nitpick comments:
In `@stations/notify/cmd/agent-notify/main.go`:
- Around line 306-308: Update the positional-argument handling around
adapter.CheckSize to calculate the total UTF-8 byte length of posArgs plus one
space separator between adjacent arguments before calling strings.Join. If the
total exceeds adapter.MaxInputBytes, return adapter.ErrInputTooLarge without
constructing the joined payload; otherwise preserve the existing join and
CheckSize flow.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository: escoffier-labs/coderabbit/.coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: bfba3f46-c894-4847-a030-e6be789d3563

📥 Commits

Reviewing files that changed from the base of the PR and between 9da6cf0 and 29fdff0.

📒 Files selected for processing (14)
  • stations/notify/cmd/agent-notify/main.go
  • stations/notify/cmd/agent-notify/main_test.go
  • stations/notify/internal/adapter/adapter.go
  • stations/notify/internal/adapter/bound.go
  • stations/notify/internal/adapter/bound_test.go
  • stations/notify/internal/adapter/claude_code_notification.go
  • stations/notify/internal/adapter/claude_code_stop.go
  • stations/notify/internal/adapter/codex_notify.go
  • stations/notify/internal/channels/discord.go
  • stations/notify/internal/channels/errors.go
  • stations/notify/internal/channels/limits.go
  • stations/notify/internal/channels/limits_test.go
  • stations/notify/internal/channels/signal.go
  • stations/notify/internal/channels/telegram.go

@solomonneas
solomonneas merged commit a9038fe into main Aug 2, 2026
28 checks passed
@solomonneas
solomonneas deleted the fix/618-bound-hook-input branch August 2, 2026 00:46
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

coderabbit-review Request one CodeRabbit review after CI is green

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(notify): bound hook input and validate provider payload sizes

1 participant