# 재개 지점의 계약
81:   * @param resumeFrom how many candidates a previous attempt durably moved
#   그리고 건너뛰는 자리의 주석
      // Everything before resumeFrom was moved and settled by the previous attempt. Re-publishing
      // it is not a retry, it is a duplicate.
      for (MessageId messageId :
          candidates.subList(Math.min(resumeFrom, candidates.size()), candidates.size())) {
        if (attempt(messageId, request)) {

# 그런데 체크포인트가 세는 것은 시도한 개수다
    List<MessageId> moved = new ArrayList<>();
    int failed = 0;
    int completed = resumeFrom;
          moved.add(messageId);
        } else {
          failed++;
        }
        completed++;
        checkpoint.accept(completed);
      }

# 그 체크포인트 값이 다음 재개 지점이 된다
    return new AdminOperationLease(
        approvalTicket,
        planDigest,
        claimed.operationId(),
        claimed.leaseOwner(),
        claimed.leaseToken(),
        claimed.itemsCompleted());
    // Either the previous attempt failed, or its lease expired without a completion. Both resume
    // from the checkpoint under a new token, which fences the previous holder out.
    return new AdminOperationRecord(
        approvalTicket,
        planDigest,
        operationId,
#   두 저널 구현이 각각 되돌아가지 않게 고정한다
128:                Math.max(current.itemsCompleted(), itemsCompleted),
JdbcAdminOperationJournal.java:76:      SET items_completed = GREATEST(items_completed, ?),

# 완료로 닫힌 승인은 다시 인수되지 않는다
    if (existing.state() == AdminOperationState.COMPLETED) {
      throw new MessageAuthorizationException(
          "APPROVAL_ALREADY_EXECUTED",
          ("approval %s was already executed to completion at %s; an approval authorises one"

# 목록은 매번 다시 조회하고, 확인되지 않은 재발행은 정착시키지 않는다
100:    List<MessageId> candidates = source.peek(request.source(), request.batchSize());
 * <p>{@code stillParked} is not simply {@code candidates - moved}. A message stays parked when its
 * republish did not confirm, and the redrive deliberately leaves it there rather than settling it —
 * the DLQ-confirm-before-settle rule applies to a redrive exactly as it does to the original
 * dead-lettering, because a redrive that settles an unconfirmed republish deletes the last copy.

# 전부 정산됐는지 묻는 술어가 이미 있다
   * Reports whether every candidate was accounted for.
   *
   * <p>An unaccounted message is a bug, not a partial success: it was neither republished nor left
   * parked, which means the redrive lost track of it.
   *
   * @return true when moved plus still-parked covers every candidate
   */
  public boolean isFullyAccounted() {
#   그 술어를 부르는 main 코드: 0
#   부르는 테스트 메서드: ApprovedPlanExecutionTest.java:214:    assertThat(accounted.isFullyAccounted()).isTrue();
ApprovedPlanExecutionTest.java:215:    assertThat(unaccounted.isFullyAccounted())

# 이 경로에는 실행 가능한 구현이 없다
  오케스트레이터를 생성하는 코드: 0
  RedriveSource 를 구현하는 main 코드: 0
  유일한 구현과 그 조회·정착
  private static final class RecordingSource implements RedriveService.RedriveSource {

    private List<MessageId> staged = List.of();
    private final List<MessageId> settled = new ArrayList<>();

    private void stage(List<MessageId> ids) {
      staged = List.copyOf(ids);
    }

    @Override
    public List<MessageId> peek(DestinationName destination, int batchSize) {
      return staged;
    }

    @Override
    public void settle(DestinationName destination, MessageId messageId) {
      settled.add(messageId);
    }
  }
