Files
2026-05-27 23:29:53 +01:00

4.5 KiB

Tasks: enterprise-message-bridge

Change ID: enterprise-message-bridge Package: @suaveplan/message-bridge Target path: universal/social/message-bridge Prerequisite packages on Verdaccio: @suaveplan/error, @suaveplan/types, @suaveplan/events, @suaveplan/retry


0. Pre-flight (non-negotiable)

  • 0.1 Confirm clean working tree (git status reports nothing) and no in-flight worktrees with uncommitted work (git worktree list then git status in each)
  • 0.2 If any worktrees exist under .claude/worktrees/, account for each one: still-active agent, work-pending-merge, or stale-and-prune. Stale worktrees MUST be removed (git worktree remove) before opening a new one — code that has been lost twice on main is the failure mode this guards against.
  • 0.3 Confirm the package set in MANIFEST.md matches find packages -maxdepth 3 -name package.json count. Drift here means a prior change archived without regenerating the manifest.

1. Scaffold

  • Create universal/social/message-bridge/ with src/, tests/, src/__benchmarks__/ and all feature subdirectories per the layout in proposal.md.
  • Write package.json at version 0.1.0 with "type": "module", "sideEffects": false, correct exports map, dependencies, and devDependencies.
  • Write tsconfig.json extending @suaveplan/typescript-config/library.json.
  • Write vitest.config.ts using createTestConfig() from @suaveplan/testing/config.
  • Add lint, typecheck, test, test:coverage, build, docs:check scripts.

2. Types + errors

  • src/types/common.ts — UnifiedMessage, MessageAttachment, SendOptions, AdapterSendOptions, MessageAdapter (interface), MessageBridgeOptions, RouteRule.
  • src/types/common.md (≥200 words, both examples, API reference).
  • src/error-codes.ts — MessageBridgeErrorCode (6 codes), metadata, register, eager call.
  • src/types/schemas.ts + schemas.md — Zod schemas.

3. Core modules

  • src/core/deduplicator/ — Deduplicator(windowMs): tracks a Map<key, expiresAt>; isDuplicate(key) returns true if key was seen within window and not expired; record(key) adds entry with now + windowMs expiry; purge() removes expired entries (called on each isDuplicate check). Tests: first occurrence not duplicate, second within window is duplicate, after window expires not duplicate, windowMs=0 always not duplicate.
  • src/routing/route-rules/ — applyRoutes(bridge, rules): subscribes to bridge.on('message', ...), matches rules by fromPlatform, calls bridge.send to toPlatform with optional transform; returns unsubscribe function. Tests: message from matching platform is forwarded, non-matching platform skipped, transform applied, unsubscribe stops forwarding.
  • src/core/message-bridge/ — MessageBridge: register(adapter) adds to internal map; start(signal) iterates registered adapters and starts each (async generators) funnelled into a shared queue; on inbound message, checks Deduplicator; if new, emits via bus and calls on('message') listeners. send(options, text) looks up adapter by options.platform, calls adapter.send. Tests: register/unregister, send to registered platform, send to unknown platform throws, deduplication suppresses second occurrence, start/stop via AbortSignal, route forwarding end-to-end with stub adapters.

4. OTel instrumentation

  • Counter message_bridge.inbound_total with attribute message_bridge.platform on each new inbound message.
  • Counter message_bridge.outbound_total with same attribute on each send.
  • Histogram message_bridge.send_duration_ms.

5. Property-based tests (tests/property.test.ts)

  • Deduplication: for arbitrary sequences of (key, timestamp) pairs with a fixed window, the deduplicator correctly reports duplicate status consistent with the window boundary.

6. Benchmarks (src/__benchmarks__/message-bridge.bench.ts)

  • Deduplicator.isDuplicate for 100 000 unique keys.

7. Docs + verify

  • One .md per implementation file (≥200 words, both examples, API reference). Root README.md.
  • bunx turbo lint typecheck test --filter=@suaveplan/message-bridge — green.
  • bunx turbo test:coverage --filter=@suaveplan/message-bridge — 100%.
  • bun scripts/publish.ts --package @suaveplan/message-bridge.
  • Archive: openspec/archive/2026-04-24-enterprise-message-bridge/.