# revision: 21234e38cdb9a926cbc92bb97a2aee2e4a7d2916

## A. this leaf has no test source set at all
main

## B. thirteen public types, files referencing them outside the owning leaf (qualified name)
OutboxRepository               7
OutboxRecord                   13
OutboxStatus                   7
OutboxLease                    6
OutboxTransitionResult         6
OutboxCanonicalMetadata        8
InboxRepository                6
InboxRecord                    0
InboxResult                    2
ClaimCheckReference            6
IdempotentMessageHandler       1
TransactionalMessageAction     1
ReliableMessagePublisher       0

## C. the two with no consumer
ReliableMessagePublisher       NONE
InboxRecord                    NONE

## D. implementors of the four ports
src/messaging/messaging-inbox-jdbc-postgresql/src/main/java/dev/caskeleton/messaging/inbox/JdbcInboxRepository.java:30:public final class JdbcInboxRepository implements InboxRepository {
src/messaging/messaging-inbox-jdbc-postgresql/src/main/java/dev/caskeleton/messaging/inbox/TransactionalInboxHandler.java:31:public final class TransactionalInboxHandler<T> implements IdempotentMessageHandler<T> {
src/messaging/messaging-inbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/inbox/IdempotentConsumerTest.java:91:final class InMemoryInbox implements InboxRepository {
src/messaging/messaging-inbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/inbox/InboxOperationsTest.java:24:  private static final class InMemoryInbox implements InboxRepository {
src/messaging/messaging-outbox-jdbc-postgresql/src/main/java/dev/caskeleton/messaging/outbox/JdbcOutboxRepository.java:48:public final class JdbcOutboxRepository implements OutboxRepository {
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxOperationsTest.java:23:  private static final class RecordingRepository implements OutboxRepository {
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxRelayTest.java:223:final class InMemoryOutboxRepository implements OutboxRepository {
src/messaging/messaging-spring-boot-starter/src/test/java/dev/caskeleton/messaging/autoconfigure/MessagingOutboxRelayLifecycleTest.java:109:  static final class CountingOutboxRepository implements OutboxRepository {

## E. OutboxRepository carries two generations of the same five transitions
22:  void append(OutboxRecord record);
67:  void markPublished(MessageId messageId, Instant now);
74:  OutboxTransitionResult markPublished(OutboxLease lease, Instant now);
85:  void markAmbiguous(MessageId messageId, String failureCode, Instant now);
88:  OutboxTransitionResult markAmbiguous(OutboxLease lease, String failureCode, Instant now);
91:  OutboxTransitionResult markAmbiguous(
100:  OutboxTransitionResult markExhausted(OutboxLease lease, String reason, Instant now);
109:  void markFailed(MessageId messageId, String failureCode, Instant now);
112:  OutboxTransitionResult markFailed(OutboxLease lease, String failureCode, Instant now);
119:  void releaseLease(MessageId messageId);
122:  OutboxTransitionResult releaseLease(OutboxLease lease);
138:  int purgePublishedBefore(Instant publishedBefore);
151:  int purgePublishedBefore(Instant publishedBefore, int limit);

## F. the older generation is called deprecated in prose but is not annotated
43:   * inspection paths and is deprecated for the relay's use.
--- any @Deprecated in the leaf?
exit=1  (1 = none)

## G. which generation the messaging relay actually calls
src/messaging/messaging-outbox-jdbc-postgresql/src/main/java/dev/caskeleton/messaging/outbox/OutboxRelay.java:158:        repository.claimBatch(owner, batchSize, leaseDuration, now, scheduler.maxAttempts());
src/messaging/messaging-outbox-jdbc-postgresql/src/main/java/dev/caskeleton/messaging/outbox/OutboxRelay.java:171:          if (repository.markPublished(lease, now) == OutboxTransitionResult.APPLIED) {
src/messaging/messaging-outbox-jdbc-postgresql/src/main/java/dev/caskeleton/messaging/outbox/OutboxRelay.java:189:                  .map(reason -> repository.markExhausted(lease, reason, now))
src/messaging/messaging-outbox-jdbc-postgresql/src/main/java/dev/caskeleton/messaging/outbox/OutboxRelay.java:192:                          repository.markAmbiguous(
src/messaging/messaging-outbox-jdbc-postgresql/src/main/java/dev/caskeleton/messaging/outbox/OutboxRelay.java:205:          if (repository.markFailed(
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:92:    List<OutboxRecord> leased = repository.leaseBatch(10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:111:    List<OutboxRecord> first = repository.leaseBatch(10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:112:    List<OutboxRecord> second = repository.leaseBatch(10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:121:    repository.leaseBatch(10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:124:        repository.leaseBatch(10, Duration.ofSeconds(30), NOW.plusSeconds(31));
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:133:    repository.leaseBatch(10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:135:    repository.markAmbiguous(record.messageId(), "CONFIRM_TIMEOUT", NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:139:    assertThat(repository.leaseBatch(10, Duration.ofSeconds(30), NOW))
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:148:    repository.leaseBatch(10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:150:    repository.markPublished(record.messageId(), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:154:    assertThat(repository.leaseBatch(10, Duration.ofSeconds(30), NOW.plusSeconds(60))).isEmpty();
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:161:    repository.leaseBatch(10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:163:    repository.markFailed(record.messageId(), "INVALID_TOPIC", NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:165:    assertThat(repository.leaseBatch(10, Duration.ofSeconds(30), NOW.plusSeconds(60))).isEmpty();
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:200:    repository.markPublished(published.messageId(), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:321:        repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:326:        repository.claimBatch("relay-b", 10, Duration.ofSeconds(30), NOW.plusSeconds(31));
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:331:    assertThat(repository.markPublished(second.get(0), NOW.plusSeconds(32)))
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:335:    assertThat(repository.markAmbiguous(first.get(0), "CONFIRM_TIMEOUT", NOW.plusSeconds(40)))
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:347:        repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), NOW).get(0);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:349:    assertThat(repository.markPublished(lease, NOW))
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:351:    assertThat(repository.markPublished(lease, NOW))
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:364:        repository.claimBatch("relay-a", 1, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:366:        repository.claimBatch("relay-b", 1, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:379:        repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), NOW).get(0).token();
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:381:        repository.claimBatch("relay-b", 10, Duration.ofSeconds(30), NOW.plusSeconds(31)).get(0);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:392:        repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), NOW, 10).get(0);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:394:    repository.markAmbiguous(lease, "CONFIRM_TIMEOUT", NOW, NOW.plusSeconds(120));
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:396:    assertThat(repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), NOW.plusSeconds(1), 10))
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:402:            repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), NOW.plusSeconds(121), 10))
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:414:          repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), clock, 3).get(0);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:415:      repository.markAmbiguous(lease, "CONFIRM_TIMEOUT", clock, clock);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:419:    assertThat(repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), clock, 3))
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:429:        repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), NOW, 10).get(0);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:431:    repository.markExhausted(lease, "budget spent without a confirmation", NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:437:            repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), NOW.plusSeconds(600), 10))
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:446:        repository.claimBatch("relay-a", 10, Duration.ofSeconds(30), NOW, 10).get(0);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:447:    repository.markAmbiguous(first, "CONFIRM_TIMEOUT", NOW, NOW.plusSeconds(60));
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:451:            .claimBatch("relay-a", 10, Duration.ofSeconds(30), NOW.plusSeconds(61), 10)
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxPostgresIT.java:453:    repository.markPublished(second, NOW.plusSeconds(62));
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxRelayTest.java:127:    assertThat(repository.leaseBatch(10, Duration.ofSeconds(30), NOW)).isEmpty();
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxRelayTest.java:134:    List<OutboxRecord> first = repository.leaseBatch(10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxRelayTest.java:135:    List<OutboxRecord> second = repository.leaseBatch(10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxRelayTest.java:144:    repository.leaseBatch(10, Duration.ofSeconds(30), NOW);
src/messaging/messaging-outbox-jdbc-postgresql/src/test/java/dev/caskeleton/messaging/outbox/OutboxRelayTest.java:147:        repository.leaseBatch(10, Duration.ofSeconds(30), NOW.plusSeconds(31));

## H. OutboxStatus.FAILED means the opposite of the legacy application enum
237:              "APPLICATION_DOES_NOT_DEPEND_ON_THE_MESSAGING_PLATFORM: the application owns its "
238-                  + "publish port and outbox model; a bridge adapter translates, and the two "
239-                  + "outbox status models mean opposite things under the same names")
240-          .allowEmptyShould(true);
241-
242-  /**
243-   * The two notification models must not learn about each other.
