배경
일반 비동기 audit 전달용 audit_event_outbox와 Knowledge physical cleanup용 knowledge_ingestion_outbox가 이미 존재한다. Knowledge Base/Document 삭제는 여전히 DB transaction 전후에 object storage를 best-effort로 삭제하므로 DB와 physical artifact가 서로 다른 상태로 남을 수 있다.
Accepted ADR-0034는 Knowledge lifecycle mutation과 canonical AuditLog row를 같은 transaction에서 commit하도록 요구한다. 따라서 nodease/mbased#299는 generic audit Outbox로 lifecycle canonical audit를 대체하지 않고, direct canonical audit와 Knowledge cleanup Outbox의 역할을 분리한다.
목표
- archive/restore/delete lifecycle mutation, direct permission cleanup, canonical AuditLog와 필요한 Knowledge cleanup intent를 한 DB transaction에서 확정한다.
- DB commit 뒤 object storage/vector/raw artifact cleanup은 기존
knowledge_ingestion_outbox와 reconciler가 수행한다.
- worker 장애, duplicate delivery, lease 만료와 acknowledgement 실패 뒤에도 hidden resource를 다시 노출하지 않고 terminal 상태로 수렴한다.
책임 경계
Transaction 계약
- Archive/restore는 lifecycle row와 canonical AuditLog를 같은 transaction에 기록한다.
- Hard delete request는 KB를
deleted로 전이해 즉시 숨기고 direct permission, canonical AuditLog, cleanup intent를 같은 transaction에 확정한다.
- Document delete는 active pointer를 해제하고 Document를
delete_pending으로 숨긴 뒤 canonical AuditLog와 cleanup intent를 같은 transaction에 확정한다.
- Audit 또는 cleanup intent add/flush/commit 실패 시 lifecycle mutation 전체를 rollback한다.
- Physical storage/provider I/O는 DB transaction과 row lock을 유지한 채 실행하지 않는다.
- Cleanup completion은 별도 lifecycle AuditLog를 만들지 않고 Outbox terminal receipt와 bounded metric으로 추적한다.
- Canonical action은
knowledge.archive, knowledge.restore, knowledge.delete를 사용하며 authorized redrive는 knowledge.cleanup.redrive로 구분한다.
Worker 및 운영 계약
- Cleanup task는 storage code/config와 Local upload volume/PVC를 가진 Knowledge worker가 소유한다.
- shared singleton Beat가
knowledge.cleanup_outbox.process를 knowledge queue에 주기적으로 등록한다.
- 기존 Log worker의 cleanup task definition은 제거한다.
- Claim과 stale recovery는 각각 bounded
SKIP LOCKED batch를 사용한다.
- Claim commit, 짧은 preparation session, external delete, owner/fence를 검증하는 completion transaction을 분리한다.
- Retry는 bounded exponential backoff, max attempts, dead-letter를 사용한다.
- Active Organization manager만 exact organization/event를 redrive할 수 있고 redrive mutation과 audit를 같은 transaction에 기록한다.
- succeeded/cancelled event는 terminal 전이 후 30일 tombstone으로 유지한 뒤 bounded cleanup한다. 미해결 dead-letter는 자동 삭제하지 않는다.
- backlog, oldest due age, retry/dead-letter와 last success를 resource ID 없는 bounded metric/log로 기록한다.
보안 계약
- Outbox에는 organization/resource/event identifier와 safe enum/opaque reference만 저장한다.
- Raw file path, source URL/title, object key, content/chunk/embedding, SQL, credential, provider payload와 raw exception을 Outbox/audit/log/trace/metric에 저장하지 않는다.
- Worker는 event owner/fence, organization, lifecycle/delete-pending state와 active reference 부재를 external I/O 전에 다시 검증한다.
- Missing/unauthorized/deleted resource는 기존 resource-hiding 계약을 유지한다.
구현 범위
- KB archive/restore/hard-delete lifecycle service/UoW
- Document delete durable cleanup cutover
- 기존 Knowledge Outbox enqueue/lease/fencing/retry/dead-letter/redrive/retention 보강
- Knowledge worker task 및 singleton Beat schedule
- Local/S3 idempotent cleanup과 DB purge completion
- safe observability와 protected redrive CLI
- Gateway/Shared/Knowledge worker unit tests 및 PostgreSQL transaction/concurrency tests
- Accepted ADR, architecture, data model, Knowledge/Audit/operational lifecycle 문서
완료 조건
- Audit 또는 cleanup intent 실패 시 lifecycle mutation이 commit되지 않는다.
- DB commit 전에 physical object delete가 호출되지 않는다.
- Delete request commit 직후 resource가 retrieval/use에서 제외된다.
- Duplicate delivery, crash replay, stale worker와 completion commit 실패가 terminal 상태로 수렴한다.
- Stale owner는 새 owner의 completion을 덮어쓰지 못한다.
- Stale recovery backlog와 normal pending work가 서로를 무기한 굶기지 않는다.
- Knowledge worker가 배포 환경에서 cleanup task를 자동 실행한다.
- Authorized redrive와 succeeded/cancelled 30일 retention이 검증된다.
- Raw locator/content/credential/provider detail이 노출되지 않는다.
- 공식 문서, 구현과 실행 가능한 테스트가 일치한다.
비범위
- RAG ranking/chunking/embedding 품질 개선
- Document process/sync durable dispatch 재설계
- Presigned upload intent와 pre-registration orphan cleanup
- Generic Audit Outbox 전체 producer 이관
- Log System repository/UoW 전역 리팩터링
- Knowledge 공개 API path/response schema 변경
배경
일반 비동기 audit 전달용
audit_event_outbox와 Knowledge physical cleanup용knowledge_ingestion_outbox가 이미 존재한다. Knowledge Base/Document 삭제는 여전히 DB transaction 전후에 object storage를 best-effort로 삭제하므로 DB와 physical artifact가 서로 다른 상태로 남을 수 있다.Accepted ADR-0034는 Knowledge lifecycle mutation과 canonical
AuditLogrow를 같은 transaction에서 commit하도록 요구한다. 따라서 nodease/mbased#299는 generic audit Outbox로 lifecycle canonical audit를 대체하지 않고, direct canonical audit와 Knowledge cleanup Outbox의 역할을 분리한다.목표
knowledge_ingestion_outbox와 reconciler가 수행한다.책임 경계
AuditLogknowledge_ingestion_outboxTransaction 계약
deleted로 전이해 즉시 숨기고 direct permission, canonical AuditLog, cleanup intent를 같은 transaction에 확정한다.delete_pending으로 숨긴 뒤 canonical AuditLog와 cleanup intent를 같은 transaction에 확정한다.knowledge.archive,knowledge.restore,knowledge.delete를 사용하며 authorized redrive는knowledge.cleanup.redrive로 구분한다.Worker 및 운영 계약
knowledge.cleanup_outbox.process를knowledgequeue에 주기적으로 등록한다.SKIP LOCKEDbatch를 사용한다.보안 계약
구현 범위
완료 조건
비범위