Skip to content

chore(release): pending release v0.47.0#698

Open
fro-bot[bot] wants to merge 2 commits into
releasefrom
next
Open

chore(release): pending release v0.47.0#698
fro-bot[bot] wants to merge 2 commits into
releasefrom
next

Conversation

@fro-bot
Copy link
Copy Markdown
Contributor

@fro-bot fro-bot Bot commented May 30, 2026

Pending Release: v0.47.0

This PR tracks changes pending release. Released on the next auto-release cycle (Sunday/Wednesday) or via manual dispatch.

Merge this PR to trigger a release. Releases also run automatically on Sunday/Wednesday at 20:00 UTC, or via manual workflow dispatch.

Commits Since Last Release


Auto-generated by the release pipeline. Updated: 2026-05-30 03:01 UTC

marcusrbrown and others added 2 commits May 29, 2026 19:58
…sages (#697)

* chore(gateway): add hono dependency for announce webhook

Adds hono@4.12.23 + @hono/node-server@1.19.14 (matching apps/workspace-agent's
pinned versions) so the gateway can host the announce webhook HTTP server.
Includes the implementation plan.

* feat(gateway): announce webhook config, HMAC, payload schema, presence posting

Building blocks for the POST /v1/announce control-plane presence webhook:
- Config: GATEWAY_WEBHOOK_SECRET, GATEWAY_PRESENCE_CHANNEL_ID, GATEWAY_HTTP_PORT
- HMAC-SHA256 verification over timestamp + '.' + rawBody (Stripe-style), with
  constant-time compare, length guards, and a replay-window check
- Effect Schema payload validation (two v1 event types; unknown rejected) with
  content-free error reasons
- Presence channel posting helper that resolves a channel by ID and sends an
  embed with allowedMentions:{parse:[]}

* feat(gateway): announce embed templates registry

Maps each announce event_type to a Discord embed with an accent color and
in-character text. Honors a non-null rendered_text override verbatim (v1 emits
null). Includes reserved color stubs for the not-yet-emitted fast-follower
event types.

* feat(gateway): announce webhook HTTP server and request handler

Adds the POST /v1/announce Hono server and the request pipeline: 8 KB size
cap, per-source rate limiting, HMAC verification, replay-window check, an
in-memory replay cache, exact-string timestamp cross-check, schema decode,
embed render, and presence post. Authentication failures return an identical
401 so callers cannot tell which check failed; the replay signature is
recorded only after a successful Discord post so retries after a post failure
still succeed. Reject logging records the reason only, never the body.

* feat(gateway): wire announce server into program lifecycle and shutdown

Starts the announce HTTP server during gateway boot and closes it in the
shutdown drain alongside the Discord client; a server-close failure is logged
without masking client teardown. New announce requests are refused with 503
while the gateway is draining for shutdown.

* fix(gateway): harden announce webhook against concurrent replay and rate-limit spoofing

- Replace the replay check/record pair with an atomic reserve/commit/release
  so two concurrent requests carrying the same signature can no longer both
  post; the reservation is released on every failure path so a legitimate
  retry after a failed post still succeeds.
- Key rate limiting on the TCP socket remote address instead of the
  caller-supplied X-Forwarded-For header, and bound the limiter to a maximum
  number of tracked keys to prevent unbounded pre-auth memory growth.
- Truncate embed descriptions to Discord's 4096-character limit so an
  over-long payload cannot wedge the control plane into endless retries.
- Drop an unreachable parse-error classification branch, share the body-size
  constant, and make the payload schema value module-private.

* docs(gateway): document announce webhook http/ layer and Schema usage

Updates the gateway agent notes for the new src/http/ announce webhook: the
fail-closed request pipeline, the generic-401 no-oracle auth behavior, the
presence posting helper, the shutdown drain that closes the HTTP server, and
the GATEWAY_ webhook config vars. Marks Effect Schema as now in use.

* fix(gateway): reject oversized announce bodies during read and bound the Discord post

- Enforce the 8 KB announce body cap with streaming bodyLimit middleware so an
  oversized request is rejected while the body is read, not after the whole
  payload has been buffered into memory. The earlier content-length precheck
  was bypassable with chunked transfer encoding, leaving an unauthenticated
  memory-pressure path; the streaming limit closes it.
- Bound the Discord fetch-and-post with a timeout so a hung call can no longer
  leave a replay reservation pinned for the process lifetime, which would have
  permanently blocked retries for that signature.
- Fall back to the templated description when rendered_text is empty or
  whitespace-only, avoiding an empty embed that Discord would reject.
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.

1 participant