# Messaging Platform Bridge Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Connect the canonical application integration-event publish boundary to the messaging platform without re-encoding bytes or introducing broker-specific ownership in app-bootstrap. **Architecture:** Add an application-owned publish port, implement it in `adapter/outbound/messaging/platformbridge`, and publish canonical pre-encoded envelopes through `EncodedMessagePublisher`. The bridge preserves identity/routing/evidence and maps platform publish evidence explicitly into application outcomes. **Tech Stack:** Java 21, Gradle 9, Spring Boot auto-configuration, JUnit 5, AssertJ. **Spec:** `docs/superpowers/specs/2026-09-18-messaging-platform-bridge-design.md` ## Global Constraints - Preserve existing uncommitted changes; do not reset, stage, commit, amend, or push. - Never invent missing canonical identity, timestamp, trace, tenant, schema, or routing values. - Never bypass `DefaultMessagePublisher` through transport SPI or native Kafka clients. - Preserve exact `ValidatedIntegrationEvent.envelopeBytes()`. - Fail closed before send when event or causation identity is not UUIDv7. - Legacy outbox storage/relay migration is outside this plan. --- ### Task 1: Application-owned canonical publish port **Files:** - Create: `application-core/src/main/java/dev/caskeleton/application/messaging/event/IntegrationEventPublishPort.java` - Test: existing bridge test compile contract **Interfaces:** - Produces: `CompletionStage publish(ValidatedIntegrationEvent event)` - [x] Create the minimal application-owned interface. - [x] Run the focused bridge test and verify remaining failures are platform dependencies/adapter implementation, not the port. ### Task 2: Outbound messaging platform API dependency **Files:** - Modify: `adapter/outbound/messaging/build.gradle` - Modify: `adapter/outbound/messaging/gradle.lockfile` through Gradle lock writing **Interfaces:** - Consumes: `:messaging:messaging-core-api`, `:messaging:messaging-schema-api`. - [x] Add only the platform API dependencies required by the bridge. - [x] Refresh this module's locks. - [x] Re-run focused bridge test and verify the missing type set is reduced to bridge production code. ### Task 3: Canonical platform bridge **Files:** - Create: `adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/platformbridge/PlatformIntegrationEventPublishAdapter.java` - Test: `adapter/outbound/messaging/src/test/java/dev/caskeleton/adapter/outbound/messaging/platformbridge/PlatformIntegrationEventPublishAdapterTest.java` **Interfaces:** - Consumes: `IntegrationEventPublishPort`, `EncodedMessagePublisher`. - Produces: canonical application-to-platform anti-corruption bridge. - [x] Implement UUIDv7 parsing that rejects incompatible identity before publisher invocation. - [x] Map canonical metadata and exact bytes into `MessageEnvelope`. - [x] Preserve non-first-class evidence in bounded `x-ca-*` headers. - [x] Map `PublishResult` using transmission evidence. - [x] Run all three focused bridge tests to GREEN. ### Task 4: Spring ownership while preserving the legacy seam **Files:** - Modify: `adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/MessagingSettings.java` - Modify: `adapter/outbound/messaging/src/main/java/dev/caskeleton/adapter/outbound/messaging/autoconfigure/MessagingBridgeRootAutoConfiguration.java` - Test: focused auto-configuration ownership test **Interfaces:** - Consumes: Spring-provided `EncodedMessagePublisher`, explicit `app.messaging.producer-id`. - Produces: `IntegrationEventPublishPort` bean for canonical events. - [x] Add explicit `producerId` to the existing `app.messaging` adapter settings. - [x] Register the canonical bridge only when `app.messaging.producer-id` is explicitly present. - [x] Keep `KafkaSender` / `KafkaMessageBroker` as a documented transitional dependency of legacy outbox/realtime only. - [x] Add a Spring test proving producer-id present => one canonical bridge bean, absent => no canonical bridge bean. - [x] Run outbound messaging tests. ### Task 5: Platform and composition regression verification **Files:** no new production files unless a test exposes a real defect. - [x] Run `:messaging:messaging-runtime-core:test`. - [x] Run `:messaging:messaging-spring-boot-starter:test`. - [x] Run `:adapter:outbound:messaging:check --warning-mode=fail`. - [x] Run `:app-bootstrap:architectureTest :app-bootstrap:systemTest --warning-mode=fail`. - [x] Search for direct app-bootstrap Kafka producer ownership. - [x] Run `git diff --check`. - [x] Report any remaining legacy outbox cutover blocker explicitly rather than inventing a migration.