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>
28 KiB
Browser file and storage recovery runbook
이 runbook은 VD-11 capability를 실제 프로젝트에서 선택한 뒤 사용하는
production 운영 template이다. 현재 skeleton에는 native reference runtime이
AVAILABLE_NOT_COMPOSED로 존재하지만 제품 dataset과 bootstrap에는 연결되지
않았으므로 이 문서 자체가 현재 서비스 incident procedure를 활성화하지 않는다.
설치 branch는 owner, dashboard, alert threshold, kill-switch key,
backend/storage 연락처와 evidence 위치를 채워야 한다.
VD-15가 설계한 origin-wide pressure/GC coordinator, OPFS/Cache forward
migration, OPFS real readiness preflight, bounded Cache cleanup과 preview decode
probe는 현재 DESIGNED_NOT_IMPLEMENTED다. 아래 절차에서 이 기능을 전제로 한
자동 조치는 해당 runtime이 구현·조합된 제품에서만 실행한다. 현재 reference
primitive를 coordinator 완료 증거로 사용하지 않는다.
OPFS 보상 실패와 reconcile (STO-01)
put()이 실패했는데 보상 cleanup effect가 확인되지 않으면 runtime은 실패를
OBJECT_RECONCILE / CONFLICT(recovery RETRY)로 보고하고 journal row를 남긴다.
이는 결함이 아니라 설계된 상태다.
- journal에
PREPARING또는FILES_READYrow가 남아 있는지 확인한다. 남아 있다면 staging bytes가 아직 존재할 수 있다는 뜻이다. maintenance.reconcile()을 실행한다. reconcile은 같은 exact physical generation token만 삭제하고, effect가 여전히EFFECT_UNKNOWN이면 journal을 유지한 채 다시OBJECT_RECONCILE을 반환한다.- journal row를 수동으로 삭제하지 않는다. row가 사라지면 stale staging을 추적할 근거가 사라지고 quota만 누수된다.
- OPFS root나 journal database를 통째로 삭제하거나 schema를 downgrade하지 않는다. rollback은 새 v2 write admission을 닫고 v1+v2 reader를 유지하는 것으로 수행한다.
1. 공통 원칙
incident 중에도 다음 작업은 금지한다.
- 자동 또는 일괄
deleteDatabase() - origin의 모든
caches.keys()삭제 - user-authored/unsynced IndexedDB 또는 OPFS data 자동 purge
- schema version downgrade
- 무한 reload/update loop
- filename, path, record/object key, URL/query, digest, body를 incident log에 복사
- fake/unavailable adapter로 바꾸고 정상 복구로 선언
공통 안전한 degrade 순서는 다음과 같다.
선택 capability의 신규 write/activation 중지
-> 진행 중 operation 정리
-> read-only
-> online-only/network-only
-> authoritative server re-read
read-only나 online-only가 사용자 작성 내용을 잃게 한다면 먼저 export/sync 경로를 제공하고 UI에 명시적으로 알린다.
2. 최초 10분
- 영향 release, browser family/version, capability와 최초 발생 시각을 확인한다.
- user dismissal과 실제 failure를 분리한다.
- safe metric의
failure_kind,phase,strategy,backend,size_bucket,release_id만으로 범위를 좁힌다. - integrity mismatch, authorization/cache classification breach, committed user-data corruption이면 신규 write/cache activation을 즉시 중지한다.
- kill switch를 가장 좁은 범위로 적용한다.
- current와 N-1 release의 schema/cache compatibility를 확인한다.
- 복구 전후 diagnostic count와 browser smoke evidence를 저장한다.
심각도 시작점:
| 상황 | 시작 심각도 |
|---|---|
| authorization 우회, private/auth response cache, content integrity mismatch | P1 |
| committed user-authored data unreadable/corrupt, widespread migration failure | P1 |
| upload/download 실패 급증, IndexedDB blocked 증가, OPFS reconstructable loss | P2 |
| enhanced picker만 실패하고 baseline 정상 | P3 |
실제 조직 severity policy가 있으면 그 정책이 우선한다.
3. File/picker/download와 별도 upload example
신호
PERMISSION_DENIED,NOT_READABLE,INTEGRITY_FAILED- closed byte stream이 failure chunk 뒤 추가 byte를 내보내거나 raw exception을 throw
- browser handoff는 정상인데 confirmed save가 감소
- large download에서 memory/stall failure
- 별도 backend upload를 설치한 feature만 session expiry/conflict, quarantined/available 전환 정체
확인 순서
- 사용자가 실제 취소한 flow가 error로 집계되지 않았는지 확인한다.
- user activation 전에 비동기 작업이 추가됐는지 확인한다.
- native input fallback이 Chromium/Firefox/WebKit에서 동작하는지 확인한다.
- count, per-file, total bytes, MIME/extension/signature policy version을 확인한다.
raw policy가 port caller에서 들어오지 않고 composition registry의 정확한
FilePolicyReferenceidentity로 resolve되는지, verification receipt가 같은 profile/file snapshot에 binding됐는지 확인한다. 같은policyKey/intention을 가진 새 객체는 거절되어야 한다. - File/OPFS/Cache/download byte source가 chunk마다 closed Result를 반환하고 첫 failure에서 consumer와 producer 모두 종료되는지 확인한다.
- download
Content-Type,Content-Disposition, CORS exposed header와 short-lived capability expiry를 확인한다. browser-managed resolver receipt가 caller의 branded receipt와 정확히 같고 resource ID, media type, safe extension, server max, optional digest와 expiry를 synchronous하게 정확히 binding하는지 확인한다. 현재 save path는 whole-object foreground streaming이며 Range resume가 아니다. partial destination에 append하지 않고, Range를 선택한 제품은 VD-14와 browser-transfer runbook의 별도 절차를 따른다. - whole-buffer API 또는 object URL lease 누수가 배포됐는지 확인한다.
- image preview를 설치했다면 object URL 발급 전에 header dimensions, pixel, decoded-byte와 animation/static-only 제한을 검사하는 VD-15 probe가 실제 조합됐는지 확인한다. 현재 byte/signature 검사만으로 decode safety를 주장하지 않는다.
- upload를 별도 설치했다면 backend 401/403/409/413/415/422/429/5xx, CORS/preflight, session TTL/clock skew, part checksum, idempotency, orphan cleanup과 quarantine queue를 그 feature runbook에서 확인한다.
안전한 조치
- enhanced open/save picker off → native input/direct authorized download
- active-content preview off
- preview pixel/decode/frame probe가 없거나 실패하면 object URL preview off
- client-generated large download off → server-side artifact generation
- broken stream adapter off → bounded fallback 또는 operation 중지; raw exception을 성공/EOF로 변환하지 않음
- upload를 별도 설치했다면 multipart concurrency/part size 하향, resumable off → approved hard cap의 simple upload, 문제 MIME 임시 차단
- expired upload session은 authorization 후 새 session; 기존 session을 재활성화하지 않음
성공 판정:
- user cancellation 제외 file/download start 대비 success rate 회복
- integrity/authorization mismatch 0
- 세 browser baseline smoke 통과
- object URL/file ref cleanup count 0 leak
- preview를 설치한 경우 malformed/oversize/animated image가 object URL 발급 전에 거절되고 native decode resource 0 leak
- upload를 별도 설치했다면 orphan session/quarantine backlog SLO와 session cleanup 0 leak
4. IndexedDB upgrade blocked/versionchange
신호
BLOCKED,UPGRADE_BLOCKED또는 blocked duration bucket 증가versionchange뒤 connection이 남음- repeated reload/update loop
- open/maintenance의
POLICY_REJECTED: immutable dataset binding missing/mismatch
확인 순서
- target schema와 current/future schema, release ID를 확인한다.
- registry-issued
authorityToken,namespaceToken,partitionToken이 같은 dataset의 승인된 값인지 확인한다. readable namespace/account/business ID를 token이나 physical DB name에 넣지 않는다. - physical DB name이 세 opaque token에서만 파생됐는지, caller
databaseNameAssertion이 exact match인지 확인한다. - governance store의 immutable scope + full
BrowserStoragePolicybinding을 versionchange, post-open, maintenance 모두에서 확인한다. raw token이나 binding 내용을 incident log에 복사하지 않는다. - old tab, worker 또는 test/debug context가 connection을 닫지 않는지 확인한다.
- 모든 connection에
versionchange/forced-close handler가 설치됐는지 확인한다. - BroadcastChannel prepare hint는 참고만 하고 실제 open/connection registry를 확인한다.
- N-1 bundle이 future schema를 read-only/online-only로 처리하는지 확인한다.
안전한 조치
- 신규 offline write와 background migration 중지
- 사용자에게 다른 tab close와 명시적 retry UI 제공
- current connection을 draining 후 close
- upgrade release rollout 중지 또는 compatible N-1 online-only로 rollback
- binding mismatch를 caller DB 이름 변경, policy 덮어쓰기 또는 DB 전체 삭제로 우회하지 않고 registry/composition 오류를 forward fix
remote tab 강제 종료, database 삭제, 무한 reload는 금지한다.
성공 판정:
- connection registry와 blocked request 0
- fresh tab과 two-tab versionchange/blocked smoke 통과
- future schema에서 N-1이 destructive write 없이 기동
- open과 maintenance에서 동일 scope/policy binding 검증 통과
5. IndexedDB migration/corruption
신호
MIGRATION_FAILED, unknown codec, schema postcondition failureCORRUPT_DATA,NOT_READABLE, forced close- transaction request success 후 commit failure
LIMIT_EXCEEDED: dataset logical byte/receipt budget 초과- lifecycle batch가 proof 없이 실행되거나 TTL/UNTIL_SYNCED record가 잘못 노출·삭제
- migration/lifecycle batch가 500 rows 또는 30,000ms를 넘거나 checkpoint 없이 중단
확인 순서
- DDL schema version과 record codec version을 구분한다.
- migration ID, last safe keyset checkpoint, revision fence,
budgetExhausted, processed/remaining bucket과 old-writer drain proof를 확인한다. - caller budget과 구현 absolute budget(500 rows/30,000ms), async operation 사이 deadline check를 확인한다.
- codec
measureStoredBytes, retention sidecarmeasuredBytes,dataset-budget.usedBytes/receiptCount가 CAS/remove/lifecycle/migration transaction과 함께 갱신됐는지 확인한다. 이 값은 native physical size가 아니다. - actual
StoredRecord가key/codecVersion/revision/payload만 포함하고writtenAtEpochMs, synchronization,measuredBytes,eligibleAtEpochMs는retentionStoresidecar에 분리돼 있는지 확인한다. - receipt retention이 31일 이하인지, configured
maxIdempotencyReceipts가 1,000,000 이하인지, prune/purge가 receipt count를 같은 transaction에서 감소시켰는지 확인한다. - TTL record가 sweep 전 read에서
EXPIRED_RESOURCE, query에서 skip되는지,UNTIL_SYNCED는CONFIRMED만 eligible한지 확인한다. - lifecycle action마다 composition의
authorizeLifecycle(action, scope, frozen policy)가 호출됐고 opaque proof가 검증 후 비영속·비관측 상태로 폐기됐는지 확인한다. - historical schema fixture에서 같은 migration을 재현한다.
- reconstructable, synced copy, unsynced/user-authored 분류를 확인한다.
- partial batch가 row/sidecar/budget/checkpoint와 원자적으로 rollback됐는지 확인한다.
- full partition purge가 record/retention/idempotency와 등록된 모든
lifecycleMetadataStores를 bounded transaction으로 정리하고 immutable governance binding은 유지하는지 확인한다. - raw record, opaque scope/proof를 ticket/log에 복사하지 않고 승인된 local recovery tooling만 사용한다.
안전한 조치
- migration 중지, repository read-only/online-only
- reconstructable만 purge/re-fetch
- synced copy는 revision 확인 후 rehydrate
- unsynced/user-authored는 quarantine marker + export/sync/recovery
- adapter bounded reopen 최대 한 번
- schema/codec compatible fix를 새 forward migration으로 배포
- migration은 old-writer drain authority를 복구한 뒤 더 작은 bounded batch로 checkpoint부터 resume
- lifecycle authority가 불명확하면 deletion을 재시도하지 않고 read-only; proof를 운영자가 수동 생성·재사용하지 않음
database 전체 삭제는 data owner가 export/recovery와 영향 scope를 승인한 별도 action이다.
성공 판정:
- historical fixture의 fresh, interrupted, resume, replay가 모두 통과
- corrupted user-authored row 자동 삭제 0
- migration canary failure 0
- N-1 rollback/read-only smoke 통과
- dataset budget/sidecar/receipt count 재검증과 bounded lifecycle fixture 통과
6. Origin quota, persistence denial, storage eviction
신호
- usage ratio pressure bucket 증가
QUOTA_EXCEEDED,STORAGE_EVICTED- startup sentinel과 logical manifest 불일치
- persistence request denied
확인 순서
estimate()가 rough origin total임을 전제로 IndexedDB/OPFS/Cache 공동 증가를 확인한다.- exact free space를 계산하거나 예약했다고 가정하지 않는다.
- expired/reconstructable, synced copy, user-authored 사용량 bucket을 분리한다.
- IndexedDB의 exact logical dataset budget과 origin-wide
estimate()를 구분한다. 전자는 codec measurement + conservative reservation이고 native physical usage/free space가 아니다. - private mode, WebView, browser storage policy와 user clear 여부를 확인한다.
- persistence denial을 capability failure가 아닌 best-effort outcome으로 처리했는지 확인한다.
안전한 조치
현재 공통 coordinator가 없으면 다음 순서를 자동 실행하거나 “exact one retry”를 보장한다고 기록하지 않는다. 제품 owner가 store별 primitive와 retention policy를 확인해 수동/feature-local로 안전하게 수행하거나 write를 read-only/online-only로 닫는다. VD-15 coordinator가 조합된 경우에만 동일 mutation owner 안에서 다음을 bounded orchestration으로 실행한다.
- 신규 speculative/reconstructable write admission 중지
- incomplete candidate와 stale staging 제거
- expired reconstructable record/object 제거
- grace가 지난 unreferenced immutable chunk 제거
- inactive public cache release 제거
- authoritative revision/sync receipt가 확인된 synced copy compact
- unsynced/user-authored sync/export UI
- 필요하면 offline read-only/online-only
각 GC invocation은 기본 100 items/5초, 구현 절대 상한 500 items/30초와 opaque cursor를 지킨다. failed write의 자동 retry는 다음 조건이 모두 맞을 때만 정확히 한 번 허용한다.
- 첫 write가 실제 quota failure로 원자적 rollback됨
- 같은 idempotency key, revision fence와 payload digest
- 외부 side effect/cross-store publish가 commit되지 않음
- bounded GC가 실제 candidate를 제거했거나 pressure가 내려감
- 현재 revision/generation 재확인과 새 admission token 발급
두 번째 failure나 effect certainty가 unknown이면 retry하지 않는다.
persist()를 boot나 반복 loop에서 요청하지 않는다. 사용자가 durable offline
기능을 선택하고 unsynced data 보호 이유를 이해하는 동작에서만 요청한다.
성공 판정:
- coordinator를 설치한 경우 pressure가 hysteresis lower bound 아래
- partial logical/physical marker mismatch는 rehydrate 또는 explicit read-only/export-required로 닫힘
- 모든 local marker가 소실된 경우 backend opaque installation epoch로
authorization 후 구분하거나
storage-reset-possibleambiguity UX를 표시함; 이를 “첫 설치로 판별 완료”라고 기록하지 않음 - user-authored 자동 purge 0
- storage clear 뒤 reconstructable rehydrate/explicit degraded UI 통과
7. OPFS partial write/corruption/worker crash
현재 capability/property probe와 native conformance test는 존재하지만 composition readiness에서 worker/lock/journal/small write-read-delete-cleanup을 한 번에 검증하는 real preflight는 아직 없다. preflight success를 운영 전제에 넣으려면 VD-15 목표 runtime을 먼저 구현한다.
신호
- journal이
PREPARING/FILES_READY에 오래 머묾 - committed logical row와 physical manifest/file 불일치
- digest/length mismatch
- worker crash, handle lock timeout,
NoModificationAllowedError - sensitive policy maintenance의
POLICY_REJECTED, proof replay/expiry 또는 authority provider/consumer unavailable
확인 순서
- mutation Web Lock owner와 timeout을 확인한다.
- worker protocol/version과 모든 sync handle의
finally close를 확인한다. - journal operation phase별 count와 age bucket을 확인한다.
- VD-15 forward migrator를 설치하지 않은 현재 v1 reference runtime에서는
physical layout이
/ca-frontend-opfs-v1/authorities/<authorityToken>/<namespaceToken>/<partitionToken>/아래의objects,chunks/sha256,staging인지 확인한다. readable namespace, filename, account ID가 path segment이면 신규 write를 중지한다. migrator를 설치한 조합에는 이 v1 path를 authoritative target 조건으로 적용하지 않는다. - journal의 physical scope binding과 logical namespace binding이 둘 다 존재하고, 같은 scope/policy fingerprint를 가리키는지 확인한다. 한쪽만 없거나 mismatch면 자동 재생성하지 않는다.
- runtime/byte-store composition의 frozen scope와 policy namespace가 일치하는지 확인한다.
LOGOUT,UNTIL_SYNCED,ACCOUNT_DELETIONmaintenance에는 composition의requestMaintenanceAuthorityprovider와consumeMaintenanceAuthorityconsumer가 둘 다 주입됐는지 확인한다. application request에는 proof 필드가 없어야 한다.- provider가 exact reason/frozen scope/frozen policy에 묶인 새 proof와 최대 5분 expiry를 발급하고, consumer가 같은 binding을 원자적으로 검증·consume해 replay를 거절하는지 확인한다. proof/token/raw scope는 log에 복사하지 않는다.
- physical path/ID/digest를 log에 복사하지 않고 reconciliation tool이 manifest schema와 digest를 검증하게 한다.
- logical row가 commit authority인지 확인한다.
- VD-15 forward migrator를 설치했다면 source/target physical layout와 journal version, migration checkpoint, copy-on-write generation, publish authority, rollback window와 N-1 reader 결과를 확인한다.
recovery
PREPARING: partial staging 검증 후 idempotent resume 또는 purgeFILES_READY: expected generation/digest 일치 시 logical commit, 아니면 quarantineCOMMITTED+ file missing/corrupt: reconstructable만 server rehydrate; user-created private는 read-only/export/recovery- stale staging/orphan chunk는 grace period와 bounded mark/sweep 후 제거
- lock/worker 문제면 OPFS write off → approved capped fallback 또는 online-only
- scope binding mismatch면 affected scope를 read-only로 격리하고 registry/ composition을 forward fix; 다른 token path로 bytes를 이동하거나 추측 복구 금지
- sensitive maintenance authority provider/consumer가 없거나 replay/expiry 검증이 실패하면 삭제를 재시도하지 않고 read-only로 전환한다. 운영자가 proof를 직접 생성·주입·재사용하지 않는다.
- forward migration 중단이면 target generation을 publish하지 않고 bounded checkpoint에서 resume한다. publish 뒤에는 source generation을 rollback window까지 보존하고, N-1이 target을 이해하지 못하면 read-only/online-only로 닫는다. source/target을 in-place 혼합하거나 layout version을 내리지 않는다.
committed object를 sync handle로 in-place repair하지 않는다. 새 generation에 정상 object를 만들고 generation CAS로 logical pointer를 전환한다.
성공 판정:
- unresolved old journal 0
- committed read integrity failure 0
- worker/handle registry 0 leak
- 각 journal phase fault injection과 concurrent put/delete/GC 통과
- sensitive maintenance의 fresh proof consume 성공, replay/expired/mismatched proof와 provider/consumer 누락은 모두 deletion 전 fail-closed
8. Cache Storage/Service Worker stale or poisoned release
public static Cache release runtime은 존재하지만 cursor/count/deadline이 있는 bounded inspect/cleanup과 Service Worker waiting/client-drain controller는 아직 없다. Service Worker는 제품이 PWA/offline fetch를 별도로 선택한 경우에만 아래 worker 절차를 적용한다.
신호
- incomplete candidate activation
- integrity/type/size mismatch
- auth/private/no-store/opaque policy rejection
- Service Worker를 별도 선택한 조합의 stale worker/update/reload loop
- active asset miss 또는 offline boot failure
확인 순서
- hosting/CDN cache와 browser Cache Storage를 별개로 확인한다.
- active/candidate/previous release ID와 manifest digest를 확인한다.
- candidate 모든 entry의 status,
expectedContentType, size, integrity 검증 marker를 확인한다. canonical manifest digest가 정규화된 Content-Type까지 binding하는지 확인한다. - 실제 response의 정규화된
Content-Type과 manifestexpectedContentType이 정확히 일치하는지 확인한다. body digest가 맞아도 type mismatch candidate는 폐기한다. - config/release manifest/auth/API가 network-only인지 확인한다.
- query/Vary exact match와
ignoreSearch/ignoreVary미사용을 확인한다. - Service Worker를 별도 선택했다면 old controlled clients와 current waiting/active worker 상태를 확인한다.
- Service Worker를 별도 선택했다면 unregister만 하고 owned cache cleanup을 빠뜨리지 않았는지 확인한다.
- cleanup caller가 cache name, release registry ID 또는 retain list를 제출할 수 없고 보존 집합이 verified active pointer와 composition retention에서만 계산되는지 확인한다.
- active pointer/release marker control JSON이 정확히 2 MiB(2,097,152 bytes) cap의 stream reader와 strict UTF-8/runtime schema를 통과하며 oversized body를 초과 지점에서 cancel하는지 확인한다.
안전한 조치
static Cache-only 조합:
- 신규 candidate activation/cache write 중지
- verified current 또는 previous release로 explicit rollback
- incomplete candidate와 runtime-public cache부터 owned-prefix cleanup
- 현재 cleanup/inspect가 cache 개수에 대해 unbounded임을 고려해 incident invocation을 추가 budget으로 반복 실행하지 않는다. VD-15 bounded cursor runtime 구현 전에는 큰 namespace를 자동 sweep하지 않는다.
Service Worker를 별도 선택한 조합에서만 추가:
- fetch interception을 network-only kill switch로 전환
- new worker activation 중지
- 필요하면 unregister + 다음 navigation cleanup migration
- old controlled client가 drain되기 전 해당 release cleanup 금지
hosting/CDN purge는 두 branch와 분리된 provider 절차로 실행한다.
auth/private response가 cache에 실제 저장됐을 가능성이 있으면 P1로 승격하고 owned affected namespace를 정확히 식별해 제거한다. origin의 unrelated cache는 삭제하지 않는다.
성공 판정:
- static Cache-only 조합은 verified active/previous release와 candidate cleanup이 일관되고 network-only fallback smoke를 통과
- Service Worker를 별도 선택한 조합만 clean/old controlled client가 같은 verified release로 수렴하고 online/offline/update/rollback smoke를 통과
- auth/private cache entry 0
- update/reload loop 0
- config/release manifest network-only header contract 통과
9. Drill evidence
실제 capability를 project catalog의 INSTALLED로 바꾸기 전에 최소 다음 drill을
실행하고 release-specific evidence를 저장한다. 이 legacy selection label은
primary status COMPOSED와 별도
TrafficAdmission/RuntimeHealth/PromotionEvidence 축이 준비된 제품 상태를
뜻하며 새로운 primary status literal이 아니다. 각 축의 literal과
contract/provider/browser/operations component gate에서 PromotionEvidence를
계산하는 규칙은 completion ledger를 그대로 따른다.
| drill | 필수 증적 |
|---|---|
| 별도 upload workflow를 설치한 경우 session abort/expiry/checksum | orphan cleanup, quarantine state, retry/idempotency |
| large save abort/integrity | partial commit 0, memory high-water |
| IndexedDB two-tab upgrade blocked | close/retry UX, connection leak 0 |
| IndexedDB governance/lifecycle | opaque scope binding, logical budget/TTL, proof discard, receipt cap |
| interrupted historical migration | old-writer drain proof, 500 rows/30s budget, checkpoint resume, atomicity, N-1 fallback |
| quota/persistence denied/storage clear | reconstructable GC, user data 보존, degraded UI |
| VD-15 coordinator를 설치한 경우 pressure/one-retry | hysteresis, bounded cursor/deadline, store priority와 retry 최대 1회 |
| OPFS journal phase crash/scope mismatch/maintenance authority | bidirectional binding, actual opaque layout, invisible partial object, reconcile summary, integrity, provider/consumer one-time proof |
| OPFS preflight/migration을 설치한 경우 | worker/lock/journal/small operation cleanup, interrupted copy-on-write와 N-1 fallback |
| cache candidate poison/update rollback | expectedContentType binding, active release 불변, previous rollback, caller retain 부재, 2 MiB control cap, auth rejection |
| bounded Cache/SW lifecycle을 설치한 경우 | cursor/count/deadline, waiting activation, controlled-client drain과 network-only rollback |
| preview probe를 설치한 경우 | pixel/decoded-byte/static-only rejection, timeout와 decode resource cleanup |
evidence에는 raw 사용자 data를 포함하지 않는다. 허용 metadata는 release/build, browser engine/version, fixture ID, fault phase, bounded counts/buckets와 PASS/FAIL 결과뿐이다.
promotion 직전에는 다음 repository evidence도 함께 보존한다.
test:browser-capabilities가 만든 JUnit에서 Chromium, Firefox, WebKit이 동일 14개 testcase set(File 2, IndexedDB 4, OPFS/Cache/StorageManager 각 1, cross-context invalidation 2, presigned streaming download/multipart upload/Image CDN 각 1)을 실제 실행해 총 42개이며 failure/error/skipped가 모두 0이어야 한다.verify:browser-capability-evidence가 engine 집합과 testcase 동일성을 기계적으로 검증한다. 현재 artifact는 Chromium/Firefox 14개씩 총 28개가 통과했지만 WebKit 실행에 필요한 native libraries(예:libbacktrace.so.0,libevent-2.1.so.7,libjxl.so.0.8,libavif.so.16과 WPE 계열)가 이 host에 없으므로 아직 promotion 가능 상태가 아니다.artifacts/quality/vite-module-inventory.json에서 optional runtime source root가 production chunk에 없음을check:optional-recipes로 검증한다.check:browser-file-storage-boundaries로 native API 경계 위반을 막고,test:browser-file-storage-removal로 runtime과 전용 gate를 제거한 격리 copy가 base typecheck/lint/architecture/test/build/catalog/CI contract를 통과함을 검증한다.- catalog의
referenceRuntime.status는AVAILABLE_NOT_COMPOSED,productionComposition은false로 유지한다. dataset owner가 모든 policy와 evidence를 승인하고 실제 composition을 추가하기 전에는INSTALLED로 해석하지 않는다.