AWS Development 관측
운영자 화면에서 만료 시각이 임박한 SUSPENSION 제재를 적용한 뒤(INT05 구간), 제재가 만료됐는데
상태가 ACTIVE 로 3시간 넘게 남았습니다.
identity.account_sanctions
id 52b9effa-69eb-4281-8bd8-0c842fdc8858
account_id 91687695-21be-4fd7-8855-6f0552395cc0
sanction_type SUSPENSION status ACTIVE
applied_at 2026-08-09 04:59:19Z
expires_at 2026-08-09 05:00:00Z ← 만료
operations.audit_events 에는 그 뒤로 이렇게 남았습니다.
target_domain=SANCTION action_type=BATCH_RETRY reason_code=UNCLASSIFIED_EXECUTION_FAILURE
actor_type=SYSTEM target_id=664a4431-7624-3737-aebc-719c7e1bda8a
180 건, 05:00:36Z ~ 08:14:45Z, 대상 1개, 약 60초 주기
배치 로그는 이것만 남깁니다.
DeadlineBatchRunner : Deadline batch completed: runId=3db4fc65-…, claimed=1, completed=0,
alreadyCompleted=0, failures=2
예외는 어디에도 없습니다. 3시간 동안 180번 실패했는데 무엇이 실패했는지 알 수 있는 기록이 없습니다.
루프가 멈춘 이유도 수정이 아니라 릴리스 31302328826 이 core 인스턴스를 교체해서 profiles: [manual]
컨테이너가 사라진 것입니다.
원인
DeadlineBatchOrchestrator.java:145-149
try {
result = Objects.requireNonNull(port.execute(item, command.runId(), command.correlationId()), "item result");
} catch (RuntimeException failure) {
result = ItemResult.retryable("UNCLASSIFIED_EXECUTION_FAILURE");
}
failure 가 로그도 없이 버려집니다. 이 클래스에는 로거가 아예 없습니다(stableCategoryFailure 도
예외를 문자열로 접기만 합니다). 그래서:
- 진단이 불가능합니다. 감사 기록은 "실패했다" 만 말하고 "무엇이" 를 말하지 않습니다. A90 이 묻는
"감사 계약이 실제로 쓸 만한가" 에 대한 답이 여기서 아니오입니다.
- 결정적 실패가 무한 재시도됩니다. 매번
retryable 로 분류되므로 같은 예외가 60초마다 되돌아옵니다.
180회 시점에도 죽은 편지함으로 가지 않았습니다. runtime-policy.json 의 attempt.maxAttempts=3
이 이 경로에 적용되지 않는 것으로 보입니다.
- 사용자에게 보이는 결과: 만료된 정지가 풀리지 않습니다. 계정이 계약보다 오래 잠긴 상태로 남습니다.
요구하는 수정
- 예외를 보존한다. 항목 식별자(category·itemId·idempotencyKey·attemptNumber)와 runId·correlationId
과 함께 ERROR 로 스택을 남긴다. 감사의 reason_code 어휘는 안정적으로 유지한다 — 예외 메시지를
감사 행에 넣어 어휘를 오염시키지 않는다.
- 같은 항목의 결정적 실패가 무한 재시도되지 않도록 시도 한도를 이 경로에 적용하거나, 한도 초과를
죽은 편지함으로 보낸다. 어느 쪽인지 명시적으로 결정하고 근거를 남긴다.
- 회귀:
port.execute 가 던질 때 (a) 원인이 기록되고 (b) 한도 초과 시 RETRYABLE_FAILURE 가 아닌
종단 처분이 되는 것을 단정한다.
부수 발견 — 감사 어휘 분화 (A90 본체)
같은 조회에서 나온 것을 함께 남깁니다. db/reconciliation/audit-vocabulary.sql 를 배포된 DB 에
처음 돌린 결과입니다.
| 관측 |
내용 |
target_domain 이 같은 개념에 둘 |
ACCOUNT_SANCTION(APPLY/LIFT) 과 SANCTION(BATCH_RETRY). 한쪽으로 필터하는 감사 검토는 나머지를 놓칩니다 |
action_type 작명이 섞임 |
맨 동사(APPLY, LIFT) vs 도메인 접두(OPERATOR_RBAC_READ_SELF, BATCH_RUN_COMPLETED) |
reason_code 의 의미가 섞임 |
APPLY→SANCTION_APPLIED(행위 반복) vs BATCH_RETRY→UNCLASSIFIED_EXECUTION_FAILURE(실제 사유) |
표본: 435건, action_type 8종, target_domain 5종, 2026-08-08~09. 작지만 분화는 명확합니다.
action_type·target_domain 이 열 곳 이상의 어댑터에서 각자 채워지고 한 곳에 정의되지 않는 것이
근본 원인입니다.
AWS Development 관측
운영자 화면에서 만료 시각이 임박한
SUSPENSION제재를 적용한 뒤(INT05 구간), 제재가 만료됐는데상태가
ACTIVE로 3시간 넘게 남았습니다.operations.audit_events에는 그 뒤로 이렇게 남았습니다.배치 로그는 이것만 남깁니다.
예외는 어디에도 없습니다. 3시간 동안 180번 실패했는데 무엇이 실패했는지 알 수 있는 기록이 없습니다.
루프가 멈춘 이유도 수정이 아니라 릴리스 31302328826 이 core 인스턴스를 교체해서
profiles: [manual]컨테이너가 사라진 것입니다.
원인
DeadlineBatchOrchestrator.java:145-149failure가 로그도 없이 버려집니다. 이 클래스에는 로거가 아예 없습니다(stableCategoryFailure도예외를 문자열로 접기만 합니다). 그래서:
"감사 계약이 실제로 쓸 만한가" 에 대한 답이 여기서 아니오입니다.
retryable로 분류되므로 같은 예외가 60초마다 되돌아옵니다.180회 시점에도 죽은 편지함으로 가지 않았습니다.
runtime-policy.json의attempt.maxAttempts=3이 이 경로에 적용되지 않는 것으로 보입니다.
요구하는 수정
과 함께 ERROR 로 스택을 남긴다. 감사의
reason_code어휘는 안정적으로 유지한다 — 예외 메시지를감사 행에 넣어 어휘를 오염시키지 않는다.
죽은 편지함으로 보낸다. 어느 쪽인지 명시적으로 결정하고 근거를 남긴다.
port.execute가 던질 때 (a) 원인이 기록되고 (b) 한도 초과 시RETRYABLE_FAILURE가 아닌종단 처분이 되는 것을 단정한다.
부수 발견 — 감사 어휘 분화 (A90 본체)
같은 조회에서 나온 것을 함께 남깁니다.
db/reconciliation/audit-vocabulary.sql를 배포된 DB 에처음 돌린 결과입니다.
target_domain이 같은 개념에 둘ACCOUNT_SANCTION(APPLY/LIFT) 과SANCTION(BATCH_RETRY). 한쪽으로 필터하는 감사 검토는 나머지를 놓칩니다action_type작명이 섞임APPLY,LIFT) vs 도메인 접두(OPERATOR_RBAC_READ_SELF,BATCH_RUN_COMPLETED)reason_code의 의미가 섞임APPLY→SANCTION_APPLIED(행위 반복) vsBATCH_RETRY→UNCLASSIFIED_EXECUTION_FAILURE(실제 사유)표본: 435건, action_type 8종, target_domain 5종, 2026-08-08~09. 작지만 분화는 명확합니다.
action_type·target_domain이 열 곳 이상의 어댑터에서 각자 채워지고 한 곳에 정의되지 않는 것이근본 원인입니다.