← Back to PRs

#9931: feat(message): configurable outbound gate preflight

by hexdaemon open 2026-02-05 22:04 View on GitHub →
stale
Adds an optional, fail-closed (default) outbound gate for message sends. - New config: `tools.message.gate` (enabled/mode/command/timeoutMs/env) - Gate runs before `executeSendAction` and can deterministically block sends. - Gate is an external command that receives JSON on stdin and returns `{allow, reason, policyVersion?}`. Motivation: MVRSA-style separation of justification/constraint from execution ("reasons can stop action") + support HexMem-backed policy. Follow-ups: - Extend to other outbound actions (react/poll/etc) - Provide a reference gate implementation that queries HexMem <!-- greptile_comment --> <h2>Greptile Overview</h2> <h3>Greptile Summary</h3> This PR introduces an optional preflight “outbound gate” for message sends, controlled by `tools.message.gate` (enabled/mode/command/timeoutMs/env). When enabled, `handleSendAction` runs an external command before `executeSendAction`; the command receives the send context as JSON on stdin and returns `{ allow, reason, policyVersion? }` on stdout. The result deterministically blocks sends when `allow` is false, with configurable fail-open vs fail-closed behavior on gate failures/timeouts. The change is localized to message send flow (`src/infra/outbound/message-action-runner.ts`) plus a new gate runner (`src/infra/outbound/outbound-gate.ts`) and the corresponding config typing (`src/config/types.tools.ts`). <h3>Confidence Score: 3/5</h3> - This PR is close to mergeable but needs fixes in the gate runner to avoid type-check/runtime lifecycle issues. - Core integration is straightforward, but the new gate runner returns unvalidated JSON fields as typed strings and can resolve the gate promise multiple times after a timeout, which can cause TypeScript build failures and unpredictable behavior under timeouts. - src/infra/outbound/outbound-gate.ts <!-- greptile_other_comments_section --> <sub>(2/5) Greptile learns from your feedback when you react with thumbs up/down!</sub> **Context used:** - Context from `dashboard` - CLAUDE.md ([source](https://app.greptile.com/review/custom-context?memory=fd949e91-5c3a-4ab5-90a1-cbe184fd6ce8)) - Context from `dashboard` - AGENTS.md ([source](https://app.greptile.com/review/custom-context?memory=0d0c8278-ef8e-4d6c-ab21-f5527e322f13)) <!-- /greptile_comment -->

Most Similar PRs