정식 승격 상태판과 증거를 동기화
This commit is contained in:
parent
34aff65cb0
commit
be08c0b573
16 changed files with 1160 additions and 63 deletions
|
|
@ -0,0 +1,134 @@
|
|||
{
|
||||
"schema": "vignette.avatar-image-resilience-recovery.v1",
|
||||
"evidence_id": "AVATAR-IMAGE-RESILIENCE-RECOVERY-2026-08-29",
|
||||
"captured_at": "2026-08-29T18:00:42+09:00",
|
||||
"privacy": {
|
||||
"raw_user_uuid_recorded": false,
|
||||
"raw_filename_recorded": false,
|
||||
"email_recorded": false,
|
||||
"resource_identity": "SHA-256 식별자만 기록"
|
||||
},
|
||||
"incident": {
|
||||
"root_cause": {
|
||||
"runtime_mode": "Python uvicorn 직접 실행 프로세스",
|
||||
"process_working_directory": "<release-root>/apps/api",
|
||||
"user_upload_dir_environment": "미설정",
|
||||
"effective_user_upload_dir": "cwd 기준 상대경로 uploads",
|
||||
"effective_storage_location": "<release-root>/apps/api/uploads",
|
||||
"docker_named_upload_volume_used_by_public_api": false,
|
||||
"failure_mechanism": "DB 경로는 승격 뒤에도 남았지만 업로드 파일은 이전 detached release root에 머물렀다. 새로 승격된 Python 직접 실행 런타임이 같은 상대 업로드 경로를 서로 다른 작업 디렉터리에서 해석해 파일을 찾지 못했다."
|
||||
},
|
||||
"initial_public_failure": {
|
||||
"phase": "복구 전",
|
||||
"http_status": 404,
|
||||
"response_content_type": "application/json",
|
||||
"browser_img_complete": true,
|
||||
"browser_img_natural_width": 0,
|
||||
"browser_img_natural_height": 0
|
||||
},
|
||||
"problem_object": {
|
||||
"path_sha256": "484dcee08b007741872ac48b49421fd45bf5a60b273e7a64c5b9a66dac85138a",
|
||||
"bytes": 28208,
|
||||
"content_sha256": "c5d06061bfa635d65f8285df242c5c9820dadcffcd785ed3f9b8619be24212c7"
|
||||
}
|
||||
},
|
||||
"recovery": {
|
||||
"source_release_commit_prefix": "bf5f7352cee0",
|
||||
"current_release_commit_prefix": "dba9b75a3887",
|
||||
"objects": [
|
||||
{
|
||||
"object_key": "recovered_object_1",
|
||||
"bytes": 18395,
|
||||
"content_sha256": "854403aed367db2d459e482a5e980fd22a846738b6034068cd7b4e80bbb7f34d"
|
||||
},
|
||||
{
|
||||
"object_key": "problem_object",
|
||||
"bytes": 28208,
|
||||
"content_sha256": "c5d06061bfa635d65f8285df242c5c9820dadcffcd785ed3f9b8619be24212c7"
|
||||
}
|
||||
],
|
||||
"object_count": 2,
|
||||
"total_bytes": 46603,
|
||||
"source_and_current_content_hashes_match": true,
|
||||
"current_release_storage_path_kind": "release root 내부의 일반 디렉터리",
|
||||
"current_release_git_dirty_paths": 0,
|
||||
"final_public_probe": {
|
||||
"http_status": 200,
|
||||
"content_type": "image/jpeg",
|
||||
"bytes": 28208,
|
||||
"content_sha256": "c5d06061bfa635d65f8285df242c5c9820dadcffcd785ed3f9b8619be24212c7",
|
||||
"matches_recovered_problem_object": true
|
||||
},
|
||||
"authenticated_browser_dom": {
|
||||
"route": "/admin/users",
|
||||
"image_complete": true,
|
||||
"natural_width": 512,
|
||||
"natural_height": 512,
|
||||
"computed_display": "block",
|
||||
"visible": true,
|
||||
"raw_source_recorded": false
|
||||
}
|
||||
},
|
||||
"ui_resilience": {
|
||||
"files": [
|
||||
"apps/web/src/components/avatar/ResilientImage.tsx",
|
||||
"apps/web/src/components/shell/Topbar.tsx",
|
||||
"apps/web/src/pages/Settings.tsx",
|
||||
"apps/web/src/pages/Onboarding.tsx",
|
||||
"apps/web/src/lib/auth.tsx",
|
||||
"apps/web/e2e/image-resilience.spec.ts",
|
||||
"apps/web/e2e/uc-settings-consent.spec.ts"
|
||||
],
|
||||
"covered_states": [
|
||||
"유효한 외부 HTTPS 이미지",
|
||||
"API 상대경로 이미지",
|
||||
"빈 소스",
|
||||
"허용하지 않는 비웹 scheme",
|
||||
"HTTP 404",
|
||||
"디코딩 또는 로드 실패",
|
||||
"지연 응답 중 0x0 비노출 로딩 상태",
|
||||
"업로드 뒤 소스 교체",
|
||||
"접근 가능한 이니셜 fallback"
|
||||
],
|
||||
"verification": {
|
||||
"typecheck": {
|
||||
"command": "npm run typecheck",
|
||||
"result": "passed"
|
||||
},
|
||||
"production_build": {
|
||||
"command": "npm run build",
|
||||
"result": "passed",
|
||||
"vite_modules_transformed": 148,
|
||||
"deterministic_runs": 2,
|
||||
"dist_file_count": 601,
|
||||
"dist_manifest_sha256": "35c48fbf844efd0514282b76937bbef3b1f173992313c7d377363d71f0806d89"
|
||||
},
|
||||
"design_ssot": {
|
||||
"command": "npm run check:design-ssot",
|
||||
"result": "passed"
|
||||
},
|
||||
"focused_e2e": {
|
||||
"command": "npx playwright test e2e/image-resilience.spec.ts e2e/uc-settings-consent.spec.ts --project=chromium-desktop --project=chromium-mobile",
|
||||
"result": "40/40 passed"
|
||||
},
|
||||
"layout_and_tabs_e2e": "17/17 passed",
|
||||
"session_layout_e2e": "8/8 passed",
|
||||
"scoped_diff_check": "passed"
|
||||
},
|
||||
"release_candidate": {
|
||||
"base_commit": "5bf89ff4ee971940882695d27f153e1460df295e",
|
||||
"commit": "35a62fda90d3ba56707acfeb3fb94090d3949f8e",
|
||||
"tree": "d8634141289b6a0007954671ece5fb7dba9c2881",
|
||||
"author": "Yun Chan",
|
||||
"clean": true,
|
||||
"protected_api_or_generated_paths_changed": 0,
|
||||
"remote_push_and_pages_deploy": "pending_explicit_external_write_approval"
|
||||
}
|
||||
},
|
||||
"stable_upload_contract": {
|
||||
"status": "pending",
|
||||
"current_recovery_scope": "현재 release root에 대한 시점 복구",
|
||||
"remaining_risk": "USER_UPLOAD_DIR가 cwd 상대경로인 동안 이후 승격이나 다른 release root 재시작에서 업로드가 다시 고립될 수 있다.",
|
||||
"required_follow_up": "사용자 업로드를 release root 밖의 절대 영속 상태 디렉터리로 옮기고, 모든 부팅·watchdog 진입점에서 USER_UPLOAD_DIR를 주입·검증한 뒤 inventory, 콘텐츠 해시 검증, 중복 제거, rollback, 공개 재시작 증거를 포함해 마이그레이션한다."
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue