# evidence 255 — messaging-capability-doc-vs-code-drift
# revision: a24ece9cf797f7ea647e33bf846b115208ed1ba5
# cwd: /shared/codebase/clean-architecture-backend-template/src/messaging
# command: bash /tmp/capdrift.sh
# ---- raw output ----
==== code: MessagingCapabilities record component order ====
    boolean brokerAcknowledgement,
    boolean replicationOrPersistenceEvidence,
    boolean perMessageSettlement,
    boolean batchSettlement,
    boolean orderedStream,
    boolean keyedOrdering,
    boolean replay,
    boolean delayedDelivery,
    boolean brokerTransaction,
    boolean deduplicatedPublish,
    boolean nativeDeadLetter,
    boolean topologyManagement) {

==== code: per-adapter CAPABILITIES arrays ====
-- messaging-kafka (KafkaMessagingTransport)
  private static final MessagingCapabilities CAPABILITIES =
      new MessagingCapabilities(
          true, true, true, true, true, true, true, false, true, false, false, true);
-- messaging-rabbit (RabbitMessagingTransport)
      new MessagingCapabilities(
          true, true, true, false, false, false, false, true, false, false, true, true);

-- messaging-kafka-share-experimental (KafkaShareWorkQueueCapability)
  public static MessagingCapabilities capabilities() {
    return new MessagingCapabilities(
        true, true, true, false, false, false, false, false, false, false, false, false);
-- messaging-pulsar-experimental (PulsarMessagingTransport, SHARED and KEY_SHARED)
  private static final MessagingCapabilities SHARED_CAPABILITIES =
      new MessagingCapabilities(
          true, true, true, true, false, false, true, true, false, false, true, true);

  private static final MessagingCapabilities KEY_SHARED_CAPABILITIES =
      new MessagingCapabilities(
          true, true, true, true, false, true, true, true, false, false, true, true);

-- messaging-nats-experimental (NatsJetStreamTransport)
  private static final MessagingCapabilities CAPABILITIES =
      new MessagingCapabilities(
          true, true, true, true, true, false, true, false, false, true, false, true);

==== doc: docs/messaging/support-matrix.md capability table ====
## Capability 매트릭스

`MessagingCapabilities`가 런타임에 선언하는 값이다. `false`인 기능을 요구하는 destination profile은
**startup에서 실패**하며, 조용히 약화되지 않는다.

| Capability | Kafka | Kafka Share | RabbitMQ | Pulsar | NATS JS |
|---|---|---|---|---|---|
| brokerAcknowledgement | O | O | O | O | O |
| replicationOrPersistenceEvidence | O | O | O | O | O |
| perMessageSettlement | O | O | O | O | O |
| batchSettlement | O | X | X | O | O |
| orderedStream | O | **X** | X | X | O |
| keyedOrdering | O | **X** | X | Key_Shared만 | X |
| replay | O | X | X | O | O |
| delayedDelivery | X | X | retry queue로 대행 | O | X |
| brokerTransaction | O | X | X | 미승격 | X |
| deduplicatedPublish | O | X | X | X | O |
| nativeDeadLetter | X | X | O | O | **X** |
| topologyManagement | O | X | O | O | O |

Kafka Share Group이 ordering 전부 `X`인 것은 설계 결정이다. share group은 개별 record를

==== code javadoc: why Kafka deduplicatedPublish is false ====
 */
public final class KafkaMessagingTransport implements MessagingTransport {

  /**
   * What this adapter can prove, with deduplicated publish set to false.
   *
   * <p>It was {@code true}, justified by producer idempotence. Producer idempotence deduplicates
   * <em>sequence retries within one producer session</em>: the producer id is reassigned on
   * restart, so the same logical message published again after a crash is a new sequence and the
   * broker stores it twice. The capability an application reads is "the broker suppresses duplicate
   * publishes of a stable id", which needs a persistent message-id store that this platform does
   * not have.
   *
   * <p>Declaring it true means {@code PublishDeduplication} is accepted and silently does nothing —
   * the caller believes the broker is deduplicating and skips the idempotency it would otherwise
   * build. False makes that request a startup failure instead, which is the whole reason the flag
   * exists.
   *
   * <p>The order of these flags is the record's: brokerAcknowledgement, replication evidence,
   * per-message settlement, batch settlement, ordered stream, keyed ordering, replay, delayed
   * delivery, broker transaction, deduplicated publish, native dead letter, topology management.
   */
  private static final MessagingCapabilities CAPABILITIES =

==== doc: support-matrix.md runtime-membership claim ====
23:> 또한 registry의 messaging leaf는 모두 `runtime_memberships`가 비어 있다. 이는 **build-only /

==== authority: src/messaging/CLAUDE.md runtime-membership section ====
## Runtime membership이 비어 있다는 것의 의미

**이 절은 한동안 사실이 아닌 채로 남아 있었다.** "registry의 모든 messaging leaf는
`runtime_memberships`가 비어 있고 따라서 build-only"라고 쓰여 있었는데, 다섯 어댑터 remediation이
`messaging-spring-boot-starter`를 `app-bootstrap` 의존성으로 넣으면서 그 closure 전체가 런타임
classpath에 올라갔다. 정확한 목록은 registry가 소유하므로 여기서 세지 않는다 — 세는 순간 다시
drift한다.

지금 의미는 이렇다:

- 대부분의 leaf는 `runtime_memberships`에 `app-bootstrap`을 갖는다. **배포된 아티팩트가 싣고 있고,
  master switch `app.messaging.enabled`로 켜진다.** 기본값은 `false`다.
- 여전히 비어 있는 leaf(experimental transport, 일부 codec, bridge, testkit)만이 build-only /
  incubating이다.
- **런타임에 있다는 것과 자격이 증명됐다는 것은 다르다.** Kafka publish 경로만 실브로커 round trip으로
  자격 검증됐고(`MessagingLiveRoundTripQualificationTest`), Rabbit·JDBC inbox/outbox·claim check·admin
  plane은 shipped, inactive, unqualified다. 이 구분은
  `MessagingMembershipQualificationTest`가 문서가 아니라 테스트로 붙들고 있다.
- 애플리케이션에 새로 배선하려면 registry의 `runtime_memberships`를 먼저 바꾸고

==== registry truth ====
shipped (runtime_memberships non-empty): 18
    messaging-admin-api
    messaging-admin-runtime
    messaging-claim-check
    messaging-cloudevents
    messaging-core-api
    messaging-inbox-jdbc-postgresql
    messaging-kafka
    messaging-observability
    messaging-outbox-jdbc-postgresql
    messaging-policy
    messaging-rabbit
    messaging-reliability-api
    messaging-runtime-core
    messaging-schema-api
    messaging-schema-json
    messaging-security
    messaging-spring-boot-starter
    messaging-transport-spi
build-only (runtime_memberships == []): 7
    messaging-kafka-share-experimental
    messaging-nats-experimental
    messaging-pulsar-experimental
    messaging-schema-avro
    messaging-schema-protobuf
    messaging-spring-cloud-stream-bridge
    messaging-testkit
