Libra CodeHub

CedarCopilot/cedar-mail

Branch: staging

feat(meetings): register Orum as a capture-only meeting webhook driver

merged#2925CedarCopilot

CedarCopilot wants to merge 2 commits into staging from worktree-send-it-orum-webhook-capture

Customer behavior verdict

Libra exercised 1 changed behavior; none regressed.

Who this touches

  • Orum deliveries are captured without creating meeting data: 348 of 163949 API requests in the last 7 days; 3 failed (0.9%).
  • Orum is available as a registered meeting provider: 348 of 163949 API requests in the last 7 days; 3 failed (0.9%).
  • Orum deliveries are acknowledged without meeting processing: 348 of 163949 API requests in the last 7 days; 3 failed (0.9%).
  • Orum is available as a registered meeting provider: 348 of 163949 API requests in the last 7 days; 3 failed (0.9%).
  • Orum webhook deliveries are captured without meeting processing: 348 of 163949 API requests in the last 7 days; 3 failed (0.9%).
  • Orum appears as a selectable meeting integration: 4 of 163949 API requests in the last 7 days; 0 failed (0%).
  • Unsigned Orum submissions can generate capture logs: Passed on this PR, but Libra could not prove the scenario can fail, so it is not counted.
  • Orum payload logs preserve bounded diagnostic fields: This scenario failed on this PR. Libra could not establish a reliable comparison with the base revision.
  • Orum is available as a registered meeting provider: Held on this PR; the scenario fails when this is broken on purpose.
  • Orum deliveries are acknowledged without meeting processing: Passed on this PR, but Libra could not prove the scenario can fail, so it is not counted.

What Libra verified

  • Orum is available as a registered meeting provider

    Libra ran this behavior against the change and confirmed the check detects when it breaks.

    Technical evidence
    • the meeting provider registry exposes Orum as a registered provider
    • Orum capability metadata identifies the provider as webhook-only and capture-only

    Changed code: constants.ts.

Live on prod, 0 of 2 surfaces working, 1 day leftTimeline and evidence
  1. Opened
    Sep 23, 2026, 3:36 PM
  2. Sep 23, 2026, 4:21 PM
  3. Merged
    Sep 23, 2026, 4:41 PM
  4. Live on prod
    Sep 23, 2026, 4:41 PM
  5. Observed 1 hour, 2 surfaces, 0 requests
    Sep 23, 2026, 4:41 PM
  6. Watching

    Live on prod, 0 of 2 surfaces working, 1 day left

    Sep 23, 2026, 4:41 PM
  7. Pipelines steady after this deploy
    Sep 23, 2026, 4:41 PM

Behaviors Libra is checking

Orum webhook deliveries to Cedar are recorded and acknowledged with HTTP 200 without resolving a user, mapping a meeting, or creating a conversation.Not checked
prod
Cedar exposes Orum as a manual, organization-scoped meeting integration with setup instructions for sending Orum call-disposition webhooks to Cedar.Not checked
prod
Malformed non-JSON Orum webhook bodies are logged with a parse error and acknowledged without throwing or emitting a trimmed-payload record.Not checked
prod
Orum bodies larger than 1,000,000 characters are not parsed or trimmed, preventing expensive processing of unauthenticated oversized requests.Not checked
prod
The raw Orum webhook body is limited to the first 60,000 characters in the received log while retaining the full body length and truncation status.Not checked
prod
The Orum endpoint accepts unsigned or unverified deliveries for capture because `x-orum-signature` is not validated until trusted processing is implemented.Not checked
prod

Libra found 2 production surfaces on prod but could not judge any of them yet. 2 surfaces had no requests at all. Libra checks hourly for 3 days after each deploy.

Summary

  • Registers orum as a meeting provider so POST /webhooks/meeting-notes/orum accepts Orum webhooks. Orum documents only the envelope ({ event, payload, test? }) and a prose list of call properties, so the driver logs each delivery and processes nothing. verify() returns unhandled_event_type, which the route answers with a 200 and no Slack page. Nothing is mapped, stored or executed.
  • The logs are meant to be the source for writing the real parser, including matching prospect phone numbers to Salesforce contacts (checked against Warp's SF: all 67 stored Orum-via-Gong contacts had a phone and 66 had an Account).
  • Lists Orum in the frontend AVAILABLE_INTEGRATIONS and the connector-card icon switches, plus the capabilities registry and docs row.

Known limits, deliberately out of scope for this driver-only PR (raised with the requester over Slack):

  • The endpoint is unauthenticated, because the customer's signing key isn't available. Anyone can post forged bodies. When writing the parser, select real deliveries by the x-orum-signature header.
  • Every delivery is recorded as auth.status=invalid / "Verification failed", because it rides unhandled_event_type. A monitor keyed on those will count Orum calls.
  • Logs hold prospect phone numbers and call transcripts on purpose. There is no retention limit or expiry yet.
  • No user can create an Orum connection: connect and initiateOAuth throw for manual providers, so the card can't self-serve.
  • The third review round's fixes (budget sharing across nesting, the trimmed-line size bound) were verified with tests and typecheck, not a fourth fresh review.

Test plan

  • TZ=UTC pnpm run autofix:local: brand check, oxlint, deps:check, mail jest, mail tz tests and server vitest (1161 files, 14486 tests) all pass. Without TZ=UTC one unrelated mail test (chatHistoryList.test.ts) fails locally in PDT. It hardcodes 12:00 UTC as "now" and is not touched by this PR.
  • pnpm --filter @zero/server run types and pnpm --filter @zero/mail run types: clean.
  • New __tests__/orum-webhook.test.ts covers:
    • registry lookup and header redaction by pattern, with the signature header kept and mixed-case headers lowercased
    • the raw-body cap, the 1M-char parse skip, and non-JSON bodies
    • key, array, depth, node and char budgets, including a nested phone surviving a huge sibling subtree
    • __proto__ keys and a 300KB transcript still keeping the phone
    • an adversarial worst-case body staying under the trimmed-line bound
  • capabilities.test.ts provider count bumped 13 to 14.

Verify in prod

  • Axiom dataset cedar-prod (or cedar-staging):
    ['cedar-prod'] | where _time > ago(1h) and message in ("[orum] webhook received", "[orum] webhook trimmed_payload")
    | project _time, message, event, body_length, body_truncated, trimmed_skipped, headers, trimmed_payload
    
  • CloudWatch log group /aws/ecs/aws-prod-api/api-service: filter on the same message strings.
  • Working: after the customer adds the webhook in Orum (Settings > System > Webhooks, "Call Disposition Added"), each call yields one [orum] webhook received line and one [orum] webhook trimmed_payload line. The route returns 200 with skipped: true, reason: unhandled_event_type. trimmed_payload should show the real field names, and headers should include x-orum-signature.
  • Regression: no lines after the customer configures the webhook (route or driver not reached), 4xx/5xx on /webhooks/meeting-notes/orum, json_parse_error set on every delivery (Orum is not sending JSON), or trimmed_skipped: 'body_too_large' on real calls (payloads over 1M chars).

Customer: Warp

šŸ¤– Generated with Claude Code

Show production surfaces and changed-file mapping

Production surfaces

SurfaceRequestsErrorsp95UsersVerdict
/webhooks/meeting-notes/orum0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.
MEETING_PROVIDER_CAPABILITIES.orum0 → 00 → 0 (0%)not measured0No traffic
No requests recorded since this deploy.

Changed files → surfaces

  • apps/mail/modules/aop/constants.tsno production surface mapped
  • apps/mail/modules/integrations/integration-card.tsxno production surface mapped
  • apps/mail/modules/integrations/meeting-integration-card.tsxno production surface mapped
  • apps/server/docs/meeting-provider-capabilities.mdno production surface mapped
  • apps/server/src/services/integrations/meetings/__tests__/capabilities.test.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/__tests__/orum-webhook.test.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/capabilities.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/index.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/orum.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/provider-ids.tsno production surface mapped
  • apps/server/src/services/integrations/meetings/types.tsno production surface mapped