Skip to content

feat(lifecycle): add dependency-free durable cleanup worker - #279

Closed
seonghobae wants to merge 20 commits into
stack/durable-deletion-receipt-ledger-v1from
review/durable-artifact-cleanup-worker-clean
Closed

feat(lifecycle): add dependency-free durable cleanup worker#279
seonghobae wants to merge 20 commits into
stack/durable-deletion-receipt-ledger-v1from
review/durable-artifact-cleanup-worker-clean

Conversation

@seonghobae

@seonghobae seonghobae commented Aug 6, 2026

Copy link
Copy Markdown
Collaborator

Objective

Implement issue #263 Slice C on the immutable receipt-ledger foundation. This Draft connects authorized deletion to receipt-first metadata tombstoning, exact-digest artifact cleanup, restart and scheduled recovery, repeat-request idempotency, and a conversion/deletion generation fence. Slice D truthful HTTP status, signed-link revocation, and accessible viewer state remain out of scope.

Exact current stack

Exact current head is bd60961fd03f1396bcd3d6695604ae0483a6a376 on immutable base branch stack/durable-deletion-receipt-ledger-v1 exact head 8448fdd98d4a6c58f4e5407fcfcce903785abaa8.

Fresh comparison reports:

  • 11 commits ahead and 0 behind;
  • merge base equals the exact receipt-foundation head;
  • 23 changed files;
  • no pom.xml, workflow, SBOM, attribution, release, version, or existing DefaultDocumentConversionService change.

Bounded implementation

  • ArtifactDeletionCoordinator persists intent before metadata tombstoning, validates exact SHA-256 or the documented absence sentinel, records controlled read/delete/mismatch failures, and replays bounded incomplete work at startup and fixed delay.
  • Per-job lifecycle locks replace process-wide coordinator synchronization, allowing unrelated document generations to progress concurrently while preserving same-job ordering.
  • LifecycleFencedArtifactStore rejects every putPdf after a durable receipt exists. An in-flight publication that wins first is snapshotted and deleted; a later publication fails closed.
  • Repeated tenant-scoped and legacy global DELETE requests resume failed receipts or observe completed receipts without recreating work.
  • WebFlux administrator DELETE executes blocking artifact work on Reactor bounded elastic rather than an event-loop thread.
  • Spring scheduling uses a pool of two threads; cleanup remains bounded to 100 receipts per pass with low-cardinality completed, failed, and pending evidence.
  • Recovery warnings expose only the exception class name, never messages, identifiers, tenant data, paths, or document metadata.

Test-first review fixes

  • Contention tests wait until competing tasks have actually started before asserting lock exclusion.
  • A blocking-service regression requires the administrator DELETE path to run on a bounded-elastic worker.
  • A legacy global-delete regression proves that a second request resumes cleanup after the first storage deletion fails and metadata has already been tombstoned.
  • A three-receipt regression proves a configured batch bound of two leaves the third receipt untouched.
  • Historical changelog language now states the tenant-scoped administrative listing contract.

All three exact predecessor-head actionable CodeRabbit threads were addressed and resolved only after the corresponding source or deterministic regression changed. Fresh exact-head CodeRabbit and OpenCode/Noema review requests were submitted; predecessor-head comments and statuses are not reused.

Acceptance state

  • exact-head fuzz run 31101322544 completed successfully across all three targets;
  • zero unresolved inline review thread currently remains;
  • exact-current-head CodeRabbit and OpenCode/Noema reviews are requested but not yet accepted;
  • CI, Security Scan, SAST, Strix, complete Maven/JaCoCo/Javadoc evidence, and counted independent write-authorized approval are absent for this stacked base and therefore not passing.

Keep this PR Draft. Parent order remains #270#268#280 receipt foundation → this Slice C. Do not resolve #268's incomplete-cleanup finding or claim product-level deletion completion until this exact slice and later Slice D pass every protection. Do not bypass protections, infer approval from advisory status, or publish a release.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

Review Change Stack

Important

Review skipped

Draft detected.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 714adf34-a1f3-4f54-881e-c3f81eaf3b8f

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

내구성 있는 삭제 영수증과 lifecycle lock을 추가했습니다. 삭제는 tombstone, checksum 검증, artifact 정리 순서로 실행됩니다. 실패한 삭제는 bounded recovery로 재시도합니다. 삭제 후 저장을 차단하고, tenant별 idempotency와 서비스 위임을 적용했습니다.

Changes

내구성 있는 artifact 삭제

Layer / File(s) Summary
삭제 계약과 설계 문서
CHANGELOG.md, docs/security/..., docs/superpowers/...
receipt-first 삭제, tombstone, checksum 검증, tenant 격리, replay 및 recovery 계약을 문서화했습니다.
Lifecycle fencing과 저장소 wiring
src/main/java/com/clearfolio/viewer/artifact/..., src/main/java/com/clearfolio/viewer/lifecycle/ArtifactLifecycleLockRegistry.java, src/main/java/com/clearfolio/viewer/config/..., src/test/java/com/clearfolio/viewer/artifact/..., src/test/java/com/clearfolio/viewer/config/..., src/test/java/com/clearfolio/viewer/lifecycle/ArtifactLifecycle...
작업별 lock으로 artifact 작업을 직렬화합니다. durable receipt 이후 putPdf를 차단합니다. 저장소 구성과 동시성 검증을 변경했습니다.
삭제 조정과 receipt recovery
src/main/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinator.java, src/main/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionMetrics.java, src/test/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinator*
tenant 및 전역 삭제, receipt 상태 전이, tombstone, checksum 검증, 실패 기록, 메트릭 및 bounded retry를 구현했습니다.
서비스 위임과 recovery scheduling
src/main/java/com/clearfolio/viewer/service/..., src/main/java/com/clearfolio/viewer/ClearfolioViewerApplication.java, src/main/resources/application.yml, src/test/java/com/clearfolio/viewer/service/...
삭제 요청을 coordinator로 위임합니다. Spring scheduling을 활성화하고 30초 지연과 실행당 100개 receipt 제한을 설정했습니다.

Estimated code review effort: 4 (Complex) | ~45 minutes

Sequence Diagram(s)

sequenceDiagram
  participant DurableDocumentDeletionService
  participant ArtifactDeletionCoordinator
  participant ConversionJobRepository
  participant ArtifactDeletionReceiptStore
  participant ArtifactStore
  DurableDocumentDeletionService->>ArtifactDeletionCoordinator: deleteForTenant(jobId, tenantId)
  ArtifactDeletionCoordinator->>ConversionJobRepository: metadata tombstone 적용
  ArtifactDeletionCoordinator->>ArtifactDeletionReceiptStore: 삭제 receipt 저장
  ArtifactDeletionCoordinator->>ArtifactStore: artifact 조회 및 checksum 검증
  ArtifactDeletionCoordinator->>ArtifactStore: artifact 삭제
  ArtifactDeletionCoordinator->>ArtifactDeletionReceiptStore: 완료 또는 retryable failure 기록
Loading

Possibly related issues

  • 이슈 263: durable tenant-safe artifact deletion lifecycle을 receipt, tombstone, retry 및 lifecycle coordination으로 구현하는 내용과 일치합니다.
🚥 Pre-merge checks | ✅ 2 | ❌ 3

❌ Failed checks (3 warnings)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning 변경 사항은 #268의 signed tenant claims와 관리자 엔드포인트 보안 요구보다 별도 cleanup 범위에 집중합니다. #268 요구를 구현하거나, 이 PR을 cleanup을 담당하는 올바른 이슈에 연결하고 보안 요구와의 범위를 명확히 분리하십시오.
Out of Scope Changes check ⚠️ Warning receipt ledger, recovery worker, lifecycle lock, fenced store, metrics 변경은 #268이 명시적으로 별도 작업으로 제외한 cleanup 범위입니다. cleanup 변경을 해당 이슈로 이동하거나, #268 범위에 필요한 보안 변경만 유지하십시오.
Docstring Coverage ⚠️ Warning Docstring coverage is 30.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (2 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed 제목은 영수증 기반 내구성 artifact 정리 작업자와 수명주기 기능 추가라는 PR의 주요 변경 사항을 명확히 요약합니다.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch review/durable-artifact-cleanup-worker-clean

Comment @coderabbitai help to get the list of available commands.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

@opencode-agent @cwl-noema-review Please independently review exact current head 076c2c3433806002a67dec7ef61df50ac460a749 against immutable receipt foundation 8448fdd98d4a6c58f4e5407fcfcce903785abaa8. Verify the bounded 19-file, one-commit Slice C: receipt-before-tombstone ordering, same-tenant repeat DELETE idempotency, cross-tenant receipt concealment, exact digest and absence-sentinel semantics, controlled retry evidence, startup/fixed-delay bounded recovery, shared per-job lifecycle lock, artifact write rejection after receipt creation, in-flight publication/deletion serialization, primary deletion-only service decoration, dependency-free aggregate evidence, standalone/MSA replaceability, unchanged pom.xml/workflows/existing conversion service, complete tests/Javadocs, and every repository protection. Do not approve or report passing evidence until the exact-head checks available for this stacked base are complete and clean.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

@seonghobae I will review PR #279 against the specified immutable foundation head. I will verify the bounded Slice C scope, implementation contracts, test coverage, and available exact-head protection evidence. I will not approve or report passing evidence until the required checks are complete and clean.

✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (6)
src/test/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinatorTest.java (2)

250-250: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

assertArrayEquals를 사용하세요.

assertTrue(Arrays.equals(...))는 실패 시 기대값과 실제값을 보고하지 않습니다. assertArrayEquals(REPLACEMENT_ARTIFACT, mismatchStore.getPdf(JOB_ID).orElseThrow())로 바꾸면 실패 진단이 쉬워집니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinatorTest.java`
at line 250, In ArtifactDeletionCoordinatorTest, replace the
assertTrue(Arrays.equals(...)) assertion with assertArrayEquals using
REPLACEMENT_ARTIFACT and mismatchStore.getPdf(JOB_ID).orElseThrow() so failures
report expected and actual byte arrays.

298-327: 🎯 Functional Correctness | 🔵 Trivial | ⚡ Quick win

배치 상한이 실제로 검증되지 않습니다.

이 테스트는 대기 영수증 2개와 maxReceiptsPerRun=2를 사용합니다. 두 값이 같으므로 Math.min(maxReceiptsPerRun, pending.size())의 상한 동작이 확인되지 않습니다. 상한을 제거해도 이 테스트는 통과합니다.

대기 영수증 수가 maxReceiptsPerRun보다 큰 경우를 추가하세요. 예: 대기 3개, 상한 2개일 때 반환값이 2이고 세 번째 영수증에는 findByJobId 상호작용이 없음을 검증하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinatorTest.java`
around lines 298 - 327, Update
recoveryBatchIsBoundedIsolatesFailuresAndUsesScheduledEntryPoint to provide
three pending receipts while retaining maxReceiptsPerRun as 2, and configure the
first two for the existing failure/success paths. Assert retryPendingWork()
returns 2 and verify the third receipt has no findByJobId interaction,
preserving the scheduled-entry-point assertions.
src/main/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinator.java (2)

159-171: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

복구 실패 로그에 예외 종류를 포함하세요.

현재 로그는 예외 정보를 전혀 남기지 않습니다. 운영자는 실패 원인을 구분할 수 없습니다. 개인정보 보호를 유지하려면 예외 클래스 이름만 기록하세요. 메시지와 식별자는 제외하세요.

♻️ 제안 리팩터
             } catch (RuntimeException exception) {
                 metrics.recordFailed();
-                log.warn("Artifact deletion recovery retained an incomplete receipt.");
+                log.warn(
+                        "Artifact deletion recovery retained an incomplete receipt. cause={}",
+                        exception.getClass().getSimpleName()
+                );
             }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinator.java`
around lines 159 - 171, Update the catch block in retryPendingWork to include
only exception.getClass().getName() in the recovery warning log, preserving the
existing message while excluding the exception message and identifiers.

207-225: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

deleteGloballyLocked에서 resumeReceiptLocked를 사용하세요.

동일한 tenant와 checksum의 기존 영수증은 상태와 관계없이 반환됩니다. 현재 코드는 메타데이터를 먼저 삭제한 뒤 markMetadataTombstoned를 호출합니다. 이 메서드는 DELETION_REQUESTED만 허용하므로 ARTIFACT_CLEANUP_FAILED 또는 ARTIFACT_CLEANUP_COMPLETED 상태에서 예외가 발생합니다. 메타데이터 삭제 후 예외가 발생하는 순서도 피해야 합니다. deleteForTenantLocked와 같이 resumeReceiptLocked(receipt)를 호출하여 실패 상태는 재시도하고 완료 상태는 no-op으로 처리하세요.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/main/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinator.java`
around lines 207 - 225, Update deleteGloballyLocked to call
resumeReceiptLocked(receipt) instead of markMetadataTombstoned after obtaining
the receipt, matching deleteForTenantLocked so failed cleanup is retried and
completed cleanup is a no-op. Ensure receipt resumption occurs before
repository.deleteById(jobId), preventing metadata deletion when resumption
rejects the receipt state.
src/main/java/com/clearfolio/viewer/ClearfolioViewerApplication.java (1)

13-13: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

스케줄러 스레드 풀 구성을 검토하세요.

Spring Boot의 기본 TaskScheduler 풀 크기는 1입니다. ArtifactDeletionCoordinator.retryPendingAfterDelay는 최대 100개의 영수증에 대해 블로킹 artifact I/O를 수행합니다. 복구 배치가 길어지면 같은 스레드를 사용하는 다른 스케줄 작업이 지연됩니다.

spring.task.scheduling.pool.size를 늘리거나 정리 작업 전용 TaskScheduler 빈을 정의하세요. 복구 실행 시간에 대한 지표도 함께 추가하면 지연을 관측할 수 있습니다.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/java/com/clearfolio/viewer/ClearfolioViewerApplication.java` at line
13, Update the scheduling configuration used by `@EnableScheduling` so
retryPendingAfterDelay does not run on Spring Boot’s single default scheduler
thread; either set spring.task.scheduling.pool.size to an appropriate value or
define a dedicated TaskScheduler bean for artifact cleanup, and add
execution-duration metrics for the recovery batch.
src/test/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinatorCoverageTest.java (1)

142-156: 📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

중복 테스트 헬퍼와 범위를 벗어난 단언을 정리하세요.

두 가지 사항이 있습니다.

  • 라인 155의 new ArtifactDeletionMetrics(null) 단언은 테스트 이름 aggregateMetricsExposeOnlyCountsAndCurrentPendingWork의 범위를 벗어납니다. 같은 단언이 ArtifactDeletionCoordinatorTest의 라인 410에도 있습니다. 여기서는 제거하세요.
  • 라인 192-200의 sha256 헬퍼는 ArtifactDeletionCoordinatorTest의 라인 581-588과 동일합니다. 공용 테스트 지원 클래스로 옮기세요. com.clearfolio.viewer.testsupport 패키지가 이미 존재합니다.

Also applies to: 192-200

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@src/test/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinatorCoverageTest.java`
around lines 142 - 156, The
aggregateMetricsExposeOnlyCountsAndCurrentPendingWork test should only verify
metric counts and current pending receipts, so remove the
ArtifactDeletionMetrics(null) assertion. Move the duplicated sha256 test helper
into a shared support class under com.clearfolio.viewer.testsupport, then update
both ArtifactDeletionCoordinatorCoverageTest and ArtifactDeletionCoordinatorTest
to reuse it and remove their local helper implementations.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@CHANGELOG.md`:
- Around line 71-72: CHANGELOG의 관리자 작업 조회 API 설명이 전체 시스템 작업을 반환하는 것으로 잘못 표현되어
있습니다. “시스템 내 전체 작업 내역”을 요청된 tenant 또는 관리자의 권한 범위에 해당하는 작업만 조회한다는 내용으로 수정하십시오.

In
`@src/main/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinator.java`:
- Around line 127-183: Remove the instance-level synchronized serialization from
deleteForTenant, deleteGlobally, and retryPendingWork, relying on lifecycleLocks
for per-job coordination. Move blocking deletion and receipt-recovery work,
including DurableDocumentDeletionService.deleteJob request-path execution, onto
a boundedElastic scheduler so WebFlux event-loop threads are not blocked;
preserve the existing per-job locking and recovery behavior.

In
`@src/test/java/com/clearfolio/viewer/lifecycle/ArtifactLifecycleLockRegistryTest.java`:
- Around line 39-45: Ensure both concurrency tests wait until the competing task
has actually started before asserting it is blocked: in
src/test/java/com/clearfolio/viewer/lifecycle/ArtifactLifecycleLockRegistryTest.java
lines 39-45, add a secondStarted latch countdown immediately before withJobLock
and await it before checking secondEntered; in
src/test/java/com/clearfolio/viewer/lifecycle/ArtifactLifecycleSerializationTest.java
lines 70-77, add deletionStarted immediately before coordinator.deleteForTenant
and await it before checking deletion.isDone().

---

Nitpick comments:
In `@src/main/java/com/clearfolio/viewer/ClearfolioViewerApplication.java`:
- Line 13: Update the scheduling configuration used by `@EnableScheduling` so
retryPendingAfterDelay does not run on Spring Boot’s single default scheduler
thread; either set spring.task.scheduling.pool.size to an appropriate value or
define a dedicated TaskScheduler bean for artifact cleanup, and add
execution-duration metrics for the recovery batch.

In
`@src/main/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinator.java`:
- Around line 159-171: Update the catch block in retryPendingWork to include
only exception.getClass().getName() in the recovery warning log, preserving the
existing message while excluding the exception message and identifiers.
- Around line 207-225: Update deleteGloballyLocked to call
resumeReceiptLocked(receipt) instead of markMetadataTombstoned after obtaining
the receipt, matching deleteForTenantLocked so failed cleanup is retried and
completed cleanup is a no-op. Ensure receipt resumption occurs before
repository.deleteById(jobId), preventing metadata deletion when resumption
rejects the receipt state.

In
`@src/test/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinatorCoverageTest.java`:
- Around line 142-156: The aggregateMetricsExposeOnlyCountsAndCurrentPendingWork
test should only verify metric counts and current pending receipts, so remove
the ArtifactDeletionMetrics(null) assertion. Move the duplicated sha256 test
helper into a shared support class under com.clearfolio.viewer.testsupport, then
update both ArtifactDeletionCoordinatorCoverageTest and
ArtifactDeletionCoordinatorTest to reuse it and remove their local helper
implementations.

In
`@src/test/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinatorTest.java`:
- Line 250: In ArtifactDeletionCoordinatorTest, replace the
assertTrue(Arrays.equals(...)) assertion with assertArrayEquals using
REPLACEMENT_ARTIFACT and mismatchStore.getPdf(JOB_ID).orElseThrow() so failures
report expected and actual byte arrays.
- Around line 298-327: Update
recoveryBatchIsBoundedIsolatesFailuresAndUsesScheduledEntryPoint to provide
three pending receipts while retaining maxReceiptsPerRun as 2, and configure the
first two for the existing failure/success paths. Assert retryPendingWork()
returns 2 and verify the third receipt has no findByJobId interaction,
preserving the scheduled-entry-point assertions.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 142b8e08-8bc4-40a8-90c0-199d2e828bc4

📥 Commits

Reviewing files that changed from the base of the PR and between 8448fdd and 076c2c3.

📒 Files selected for processing (19)
  • CHANGELOG.md
  • docs/security/2026-08-06-durable-artifact-deletion-receipts.md
  • docs/superpowers/plans/2026-08-06-durable-artifact-cleanup.md
  • docs/superpowers/specs/2026-08-06-durable-artifact-cleanup-design.md
  • src/main/java/com/clearfolio/viewer/ClearfolioViewerApplication.java
  • src/main/java/com/clearfolio/viewer/artifact/LifecycleFencedArtifactStore.java
  • src/main/java/com/clearfolio/viewer/config/ArtifactStoreConfig.java
  • src/main/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinator.java
  • src/main/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionMetrics.java
  • src/main/java/com/clearfolio/viewer/lifecycle/ArtifactLifecycleLockRegistry.java
  • src/main/java/com/clearfolio/viewer/service/DurableDocumentDeletionService.java
  • src/main/resources/application.yml
  • src/test/java/com/clearfolio/viewer/artifact/LifecycleFencedArtifactStoreTest.java
  • src/test/java/com/clearfolio/viewer/config/ArtifactStoreConfigTest.java
  • src/test/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinatorCoverageTest.java
  • src/test/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinatorTest.java
  • src/test/java/com/clearfolio/viewer/lifecycle/ArtifactLifecycleLockRegistryTest.java
  • src/test/java/com/clearfolio/viewer/lifecycle/ArtifactLifecycleSerializationTest.java
  • src/test/java/com/clearfolio/viewer/service/DurableDocumentDeletionServiceTest.java

Comment thread CHANGELOG.md Outdated
Comment thread src/main/java/com/clearfolio/viewer/lifecycle/ArtifactDeletionCoordinator.java Outdated

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Please review exact current head 6571169c12d3a63421ff20e5d3e27e1884465410. The prior actionable findings were addressed test-first: contender latches now prove real lock contention; process-wide synchronization was removed in favor of per-job lifecycle locks; blocking admin DELETE work is subscribed on bounded elastic; legacy global deletion resumes existing failed/completed receipts before metadata mutation; the historical changelog is tenant-scoped; and the scheduler pool is explicitly bounded above one thread. Do not reuse predecessor-head evidence.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

@seonghobae I will review exact head 6571169c12d3a63421ff20e5d3e27e1884465410 independently. I will not reuse predecessor-head evidence. I will verify the stated fixes and the Slice C lifecycle, tenancy, concurrency, recovery, and repository-protection requirements before reporting results.

⚠️ Action not completed

Head commit changed.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

@coderabbitai review

Review exact current head bd60961fd03f1396bcd3d6695604ae0483a6a376. The exact-head fuzz run 31101322544 completed successfully. This request supersedes the review that covered only through 6571169c12d3a63421ff20e5d3e27e1884465410; the final bounded-batch regression is part of the current head. Keep the PR Draft and do not reuse predecessor-head acceptance.

@coderabbitai

coderabbitai Bot commented Aug 6, 2026

Copy link
Copy Markdown

@seonghobae I will review exact head bd60961fd03f1396bcd3d6695604ae0483a6a376 independently.

I will include the final bounded-batch regression. I will treat fuzz run 31101322544 as reported evidence only until the exact-head checks are verified. I will not reuse predecessor-head acceptance. The PR will remain Draft.

⚠️ Action not completed

Review rate limited.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

Copy link
Copy Markdown
Collaborator Author

@opencode-agent review
@noema-agent review
@cwl-noema-review

Please independently review exact current head bd60961fd03f1396bcd3d6695604ae0483a6a376 only. Verify receipt-first durability, strict tenant concealment, immutable job-generation fencing, restart replay, digest-bound cleanup, repeated tenant/global DELETE idempotency, per-job concurrency, WebFlux bounded-elastic isolation, privacy-safe recovery evidence, and the deterministic batch-bound regressions. Exact-head fuzz 31101322544 succeeded; CI, Security Scan, SAST, Strix, full Maven/JaCoCo/Javadoc, and independent approval remain absent on this stacked base and must not be inferred. Do not reuse predecessor-head comments or approvals.

Copy link
Copy Markdown
Collaborator Author

Superseded by #283. Exact final worker blobs from bd60961fd03f1396bcd3d6695604ae0483a6a376 are preserved byte-for-byte in one clean commit a32a0978cabcaa4b0c4812942cdec8e723e272f0 on receipt foundation v2 8c803dafd14c1b6e7cac80b39e5c5a9915fc1cbd, which directly inherits current parent tenant isolation. #283 is 1 commit / 23 files / 0 behind with no dependency, workflow, release, or existing conversion-service drift. Closing this automation-mutated older-base Draft unmerged; all predecessor checks/reviews are stale.

@seonghobae seonghobae closed this Aug 6, 2026

Copy link
Copy Markdown
Collaborator Author

Closing as superseded by clean-stack PR #283. #283 is based on receipt foundation v2, preserves the reviewed cleanup-worker implementation, carries the strict replay RED/GREEN hardening, and includes the operator cleanup runbook at exact head 052130cb364ebcf3401bc76e905f2473b554cae1. This v1 branch remains ancestry-diverged from its advanced parent and duplicates the same bounded Slice C. Exact-head fuzz/review/check evidence from this PR is not transferred; #283 must complete its own gates.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant