fix: preserve OPFS recovery authority during cleanup
Repair the compensating half of the OPFS put saga. The coordinator now owns a single abortPreparedPut() driven by a composition-owned bounded signal instead of the caller's already aborted one, and the worker client no longer issues a duplicate fire-and-forget abort. Journal rows and budget reservations are released only after the physical effect is confirmed CLEANED or ALREADY_CLEAN; a timeout, malformed response or EFFECT_UNKNOWN keeps PREPARING/FILES_READY and returns OBJECT_RECONCILE. New writes carry a transaction-unique physicalGenerationId through the staging receipt, manifest path and prepared object, so a late compensation deletes only its own transaction's directory even when a newer transaction legitimately reuses the same logical generation. v1 paths, receipts and prepared objects stay readable through the rollback window. Abort and cleanup hold the origin mutation lease through physical deletion and staging removal. A transaction that never reached staging returns ALREADY_CLEAN without waiting for the lease, which would otherwise deadlock against the BEGIN it is cancelling. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6d1e44f206
commit
618da9abf5
@@ -88,7 +88,7 @@ Rollout state starts at `NOT_STARTED`; documented-unimplemented items start at
|
||||
|
||||
| ID | Activation | Red test command | Fix commit/PR | Rollout state | Rollback trigger | Evidence |
|
||||
| --- | --- | --- | --- | --- | --- | --- |
|
||||
| STO-01 | OPFS not composed in template; **Critical** for any product writer | `corepack pnpm exec vitest run tests/unit/opfs-byte-store.test.ts tests/unit/indexeddb-opfs-journal.test.ts` | — | `NOT_STARTED` | OPFS reconcile backlog or journal growth | — |
|
||||
| STO-01 | OPFS not composed in template; **Critical** for any product writer | `corepack pnpm exec vitest run tests/unit/opfs-byte-store.test.ts tests/unit/opfs-worker-runtime.test.ts tests/unit/indexeddb-opfs-journal.test.ts` | `fix: preserve OPFS recovery authority during cleanup` | `FIXED_NOT_RELEASED` | OPFS reconcile backlog or journal growth | Red 4 new saga cases → green 25/25 across the three OPFS suites; `check:types` PASS (incl. web-worker); `check:browser-file-storage-boundaries` PASS; `lint` PASS; `test:unit` 1511 passed with only the pre-existing environmental `ci-artifact-contract` failures |
|
||||
| STO-02 | Browser file runtime not composed | `corepack pnpm exec vitest run tests/unit/browser-file-download.test.ts` | — | `NOT_STARTED` | download navigation blocked by canonical target | — |
|
||||
| STO-03 | Public cache not composed | `corepack pnpm exec vitest run tests/unit/public-response-cache.test.ts` | — | `NOT_STARTED` | composition rejection of an existing policy | — |
|
||||
| STO-04 | Public cache not composed | `corepack pnpm exec vitest run tests/unit/public-response-cache.test.ts` | — | `NOT_STARTED` | restage loop or bandwidth spike | — |
|
||||
|
||||
@@ -13,6 +13,24 @@ probe는 현재 `DESIGNED_NOT_IMPLEMENTED`다. 아래 절차에서 이 기능을
|
||||
자동 조치는 해당 runtime이 구현·조합된 제품에서만 실행한다. 현재 reference
|
||||
primitive를 coordinator 완료 증거로 사용하지 않는다.
|
||||
|
||||
|
||||
## OPFS 보상 실패와 reconcile (STO-01)
|
||||
|
||||
`put()`이 실패했는데 보상 cleanup effect가 확인되지 않으면 runtime은 실패를
|
||||
`OBJECT_RECONCILE` / `CONFLICT`(recovery `RETRY`)로 보고하고 journal row를 남긴다.
|
||||
이는 결함이 아니라 설계된 상태다.
|
||||
|
||||
1. journal에 `PREPARING` 또는 `FILES_READY` row가 남아 있는지 확인한다. 남아
|
||||
있다면 staging bytes가 아직 존재할 수 있다는 뜻이다.
|
||||
2. `maintenance.reconcile()`을 실행한다. reconcile은 같은 exact physical
|
||||
generation token만 삭제하고, effect가 여전히 `EFFECT_UNKNOWN`이면 journal을
|
||||
유지한 채 다시 `OBJECT_RECONCILE`을 반환한다.
|
||||
3. journal row를 수동으로 삭제하지 않는다. row가 사라지면 stale staging을 추적할
|
||||
근거가 사라지고 quota만 누수된다.
|
||||
4. OPFS root나 journal database를 통째로 삭제하거나 schema를 downgrade하지
|
||||
않는다. rollback은 새 v2 write admission을 닫고 v1+v2 reader를 유지하는 것으로
|
||||
수행한다.
|
||||
|
||||
## 1. 공통 원칙
|
||||
|
||||
incident 중에도 다음 작업은 금지한다.
|
||||
|
||||
Reference in New Issue
Block a user