{
"version": "v2.5.5",
"status": "released",
"releaseScopes": [
"contracts-package",
"coupler-api",
"docs"
],
"extraRepoRefs": [
"coupler-admin-web",
"coupler-mobile-app"
],
"versionMapping": {
"docs": {
"tag": "v2.5.5",
"commit": null
},
"coupler-api": {
"tag": "v2.5.7",
"commit": "dabfc71ac74583e01be1c054d8bedc64c740fc52"
},
"coupler-admin-web": {
"tag": null,
"commit": "44ca0d1acfe02cdd205dc188a957781d26746ac2"
},
"coupler-mobile-app": {
"store": {
"android": {
"versionBuild": "2.5.1 (107)",
"releaseTag": "v2.5.1",
"commit": "2a9ee166e30d77f827d49ac4ddb643ea775606fa",
"sourceStatus": "verified",
"limitation": null
},
"ios": {
"versionBuild": "2.5.1 (107)",
"releaseTag": "v2.5.1",
"commit": "2a9ee166e30d77f827d49ac4ddb643ea775606fa",
"sourceStatus": "verified",
"limitation": null
}
},
"nextPush": null,
"commit": null
}
},
"scopeResults": {
"contracts-package": {
"status": "released",
"summary": "stable 0.1.43 발행과 Admin #125·Mobile #265 main의 dependency·lockfile 정렬, 설치 및 품질 Gate를 완료했다.",
"evidence": {
"publishedPackage": "@coupler-developer/coupler-api-contracts@0.1.43",
"workflow": "https://github.com/coupler-developer/coupler-api/actions/runs/33950312627",
"sourceRef": "dabfc71ac74583e01be1c054d8bedc64c740fc52",
"sourceTree": {
"path": "packages/contracts",
"publishedSourceTree": "a85c9fbbb262b42ca7f99387b9f0d59aa718637c",
"releaseSourceTree": "a85c9fbbb262b42ca7f99387b9f0d59aa718637c"
}
}
},
"coupler-api": {
"status": "released",
"summary": "개발계·운영계에 dabfc71a를 반영하고 canonical 응답·업데이트 경로·legacy 필드 제거를 확인했으며 API v2.5.7 태그를 고정했다.",
"evidence": {
"deployment": "2026-09-05 개발계 development 배포·smoke 후 출시 책임자의 최종 운영 실행 승인으로 16:53:53 KST 운영 배포를 시작했다. frozen install과 PM2 production 설정으로 dabfc71ac74583e01be1c054d8bedc64c740fc52를 반영하고 16:54:07 KST 내부·외부 root HTTP 200을 확인했다. PM2 시작 16:53:57.758 KST·online·재시작 44회, source clean. 16:54:49 KST 기능 postcheck 바로 다음 Gate에서 원격 annotated tag v2.5.7의 peeled commit이 같은 SHA임을 확인했다. DB·cron·CMS 최소 버전·NextPush 변경 없음.",
"smoke": "개발계 2026-09-05 16:21 KST exact dabfc71a, manager/all 11건·detail/17 url·이미지 HEAD 1건 200, 배포 lounge list/myList/detail presenter pinned=Y·legacy 없음 PASS. 운영 배포 전 16:16 KST exact 1a44d374의 내부 HTTP 기준점과 비교해, 배포 후 16:54:49 KST exact dabfc71a의 공개 HTTPS manager/all 6건·detail/16 image slice 4건·이미지 HEAD 5건 200을 확인했다. 운영 canonical profile_image_path/detail_profile 및 lounge pinned=Y 보존, profile/detail_profile_set/best 없음 PASS. google/apple build105 force_update=2, build107=0, min_version107·Store HTTPS 링크 유지. 라운지는 배포된 순수 presenter 합성 입력이며 로그인 사용자 HTTP나 기기 UI 관측이 아니다. WebSocket·Admin 경로는 불변 source와 기존 CI를 재사용했다. 재시작 전 16:53:55 KST Google Play 구매 조회 permissionDenied 401도 관측되어 cutover와 별도 운영 문제로 남겼다.",
"publicContract": {
"apiRefs": {
"previous": "1a44d3747fbc8042cb1c78021c404ccb62156618",
"current": "dabfc71ac74583e01be1c054d8bedc64c740fc52"
},
"contractRefs": {
"previous": "@coupler-developer/coupler-api-contracts@0.1.42",
"current": "@coupler-developer/coupler-api-contracts@0.1.43"
},
"consumers": [
{
"state": "present",
"id": "previous-store",
"surface": "mobile-store",
"generation": "previous",
"artifact": {
"kind": "store-builds",
"mappingRef": "Store 2.5.0 (105), source 0baa63aee1cc4e64456affdd7b914c80360824e5",
"iosVersionBuild": "2.5.0 (105)",
"androidVersionBuild": "2.5.0 (105)"
},
"contractRef": "@coupler-developer/coupler-api-contracts@0.1.32",
"interfaces": [
"rest",
"websocket",
"bootstrap",
"version"
],
"interfaceInventoryEvidence": "2.5.0 source의 매니저 profile/detail_profile_set, lounge best, concierge WebSocket 및 auth/getSettingList를 조사했다. 지원 최소 build 107 아래의 제품 화면은 지원 종료 대상이며 강제 업데이트 경로는 유지한다."
},
{
"state": "present",
"id": "current-store",
"surface": "mobile-store",
"generation": "current",
"artifact": {
"kind": "store-builds",
"mappingRef": "Android 2.5.1 (107); iOS 2.5.1 (107)",
"iosVersionBuild": "2.5.1 (107)",
"androidVersionBuild": "2.5.1 (107)"
},
"contractRef": "@coupler-developer/coupler-api-contracts@0.1.41",
"interfaces": [
"rest",
"websocket",
"bootstrap",
"version"
],
"interfaceInventoryEvidence": "양 Store source 2a9ee166e30d77f827d49ac4ddb643ea775606fa: profile_image_path/detail_profile/pinned 사용, concierge WebSocket과 설정 조회 유지. 이번에는 새 Store binary를 만들지 않는다."
},
{
"state": "present",
"id": "previous-ota",
"surface": "mobile-nextpush",
"generation": "previous",
"artifact": {
"kind": "nextpush-deployment",
"mappingRef": "existing source 88a6d851e13c3012077ded501b79abe6e577308d; Android v34; iOS v31",
"android": {
"app": "bluedotstudio.official-gmail.com/coupler",
"deployment": "Production",
"label": "v34",
"cohort": "100% mandatory enabled",
"targetBinary": "2.5.1"
},
"ios": {
"app": "bluedotstudio.official-gmail.com/coupler-ios",
"deployment": "Production",
"label": "v31",
"cohort": "100% mandatory enabled",
"targetBinary": "2.5.1"
}
},
"contractRef": "@coupler-developer/coupler-api-contracts@0.1.41",
"interfaces": [
"rest",
"websocket",
"bootstrap",
"version"
],
"interfaceInventoryEvidence": "2026-09-05 16:09 KST Production history에서 기존 양 platform label·target을 확인했다. source 88a6d851은 공통 시작·복귀 업데이트 gate와 canonical DTO를 사용한다. previous는 이번 API 릴리스 이전에 발행된 artifact 분류다."
},
{
"state": "absent",
"id": "current-ota",
"surface": "mobile-nextpush",
"generation": "current",
"owner": "릴리스 책임자",
"absenceEvidence": "이번 API-only cutover에서는 신규 OTA를 발행하지 않는다. 실제 제공 중인 Android v34/iOS v31은 previous-ota inventory로 계속 포함한다."
},
{
"state": "present",
"id": "previous-admin",
"surface": "admin",
"generation": "previous",
"artifact": {
"kind": "admin-build",
"artifactRef": "59cb4862064c0e963bd0a6ce57673996d77ff290"
},
"contractRef": "@coupler-developer/coupler-api-contracts@0.1.41",
"interfaces": [
"rest",
"websocket"
],
"interfaceInventoryEvidence": "docs v2.5.4에 고정된 운영 CMS artifact를 유지한다. Admin pinned/매니저 편집 계약과 conciergeRealtime 경로는 API #237에서 변경하지 않았다."
},
{
"state": "present",
"id": "current-admin",
"surface": "admin",
"generation": "current",
"artifact": {
"kind": "admin-build",
"artifactRef": "44ca0d1acfe02cdd205dc188a957781d26746ac2"
},
"contractRef": "@coupler-developer/coupler-api-contracts@0.1.43",
"interfaces": [
"rest",
"websocket"
],
"interfaceInventoryEvidence": "Admin #125의 계약 정렬 source와 로컬 production build를 검증하는 후보 inventory다. 새 CMS 배포로 주장하지 않으며 운영 artifact는 previous-admin을 유지한다. package 0.1.41→0.1.43은 package version과 type-only best 삭제뿐이어서 runtime exports는 같다."
}
],
"cases": [
{
"id": "previous-store-rest-activate",
"consumerId": "previous-store",
"interface": "rest",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a 공개 HTTPS manager/all 6건·detail/16 image slices 4건·이미지 HEAD 5건 200, 실제 배포 lounge list/myList/detail presenter pinned=Y PASS. profile_image_path/detail_profile/pinned는 유지하고 profile/detail_profile_set/best는 없다. 현재 Store107·기존 OTA source의 canonical 소비와 일치한다. 지원 종료105가 직접 받는 제품 요청은 HTTP 성공하되 legacy 이미지·고정글 표시가 없는 허용된 기능 저하이며, 모든105 요청을 서버가 차단한다고 주장하지 않는다."
},
{
"id": "previous-store-rest-restore-api",
"consumerId": "previous-store",
"interface": "rest",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST previous API 1a44d374 운영 HTTP manager/all 6건·manager/detail/16 image slice 4건·이미지 HEAD 5건 200, 실제 lounge list/myList/detail presenter의 pinned=Y 및 best alias 유지 PASS. Admin REST는 변경 범위 밖이며 기존 source·CI로 보존 경계를 확인했다."
},
{
"id": "previous-store-websocket-activate",
"consumerId": "previous-store",
"interface": "websocket",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "API #237은 REST presenter와 type/Swagger만 변경한다. WebSocket 코드·인증·wire 계약 불변 및 기존 CI 성공을 보존 근거로 사용한다. 별도 사용자 세션 생성은 하지 않는다."
},
{
"id": "previous-store-websocket-restore-api",
"consumerId": "previous-store",
"interface": "websocket",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "API 1a44d374..dabfc71a의 13개 변경 파일에 WebSocket·인증·queue 코드가 없고 기존 handler와 메시지 계약은 byte-equivalent다. CI Core tests 성공을 재사용한다. 새 사용자 WebSocket 세션을 열었다고 주장하지 않는다."
},
{
"id": "previous-store-bootstrap-activate",
"consumerId": "previous-store",
"interface": "bootstrap",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
},
{
"id": "previous-store-bootstrap-restore-api",
"consumerId": "previous-store",
"interface": "bootstrap",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
},
{
"id": "previous-store-version-activate",
"consumerId": "previous-store",
"interface": "version",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
},
{
"id": "previous-store-version-restore-api",
"consumerId": "previous-store",
"interface": "version",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
},
{
"id": "current-store-rest-activate",
"consumerId": "current-store",
"interface": "rest",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a 공개 HTTPS manager/all 6건·detail/16 image slices 4건·이미지 HEAD 5건 200, 실제 배포 lounge list/myList/detail presenter pinned=Y PASS. profile_image_path/detail_profile/pinned는 유지하고 profile/detail_profile_set/best는 없다. 현재 Store107·기존 OTA source의 canonical 소비와 일치한다. 지원 종료105가 직접 받는 제품 요청은 HTTP 성공하되 legacy 이미지·고정글 표시가 없는 허용된 기능 저하이며, 모든105 요청을 서버가 차단한다고 주장하지 않는다."
},
{
"id": "current-store-rest-restore-api",
"consumerId": "current-store",
"interface": "rest",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST previous API 1a44d374 운영 HTTP manager/all 6건·manager/detail/16 image slice 4건·이미지 HEAD 5건 200, 실제 lounge list/myList/detail presenter의 pinned=Y 및 best alias 유지 PASS. Admin REST는 변경 범위 밖이며 기존 source·CI로 보존 경계를 확인했다."
},
{
"id": "current-store-websocket-activate",
"consumerId": "current-store",
"interface": "websocket",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "API #237은 REST presenter와 type/Swagger만 변경한다. WebSocket 코드·인증·wire 계약 불변 및 기존 CI 성공을 보존 근거로 사용한다. 별도 사용자 세션 생성은 하지 않는다."
},
{
"id": "current-store-websocket-restore-api",
"consumerId": "current-store",
"interface": "websocket",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "API 1a44d374..dabfc71a의 13개 변경 파일에 WebSocket·인증·queue 코드가 없고 기존 handler와 메시지 계약은 byte-equivalent다. CI Core tests 성공을 재사용한다. 새 사용자 WebSocket 세션을 열었다고 주장하지 않는다."
},
{
"id": "current-store-bootstrap-activate",
"consumerId": "current-store",
"interface": "bootstrap",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
},
{
"id": "current-store-bootstrap-restore-api",
"consumerId": "current-store",
"interface": "bootstrap",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
},
{
"id": "current-store-version-activate",
"consumerId": "current-store",
"interface": "version",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
},
{
"id": "current-store-version-restore-api",
"consumerId": "current-store",
"interface": "version",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
},
{
"id": "previous-ota-rest-activate",
"consumerId": "previous-ota",
"interface": "rest",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a 공개 HTTPS manager/all 6건·detail/16 image slices 4건·이미지 HEAD 5건 200, 실제 배포 lounge list/myList/detail presenter pinned=Y PASS. profile_image_path/detail_profile/pinned는 유지하고 profile/detail_profile_set/best는 없다. 현재 Store107·기존 OTA source의 canonical 소비와 일치한다. 지원 종료105가 직접 받는 제품 요청은 HTTP 성공하되 legacy 이미지·고정글 표시가 없는 허용된 기능 저하이며, 모든105 요청을 서버가 차단한다고 주장하지 않는다."
},
{
"id": "previous-ota-rest-restore-api",
"consumerId": "previous-ota",
"interface": "rest",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST previous API 1a44d374 운영 HTTP manager/all 6건·manager/detail/16 image slice 4건·이미지 HEAD 5건 200, 실제 lounge list/myList/detail presenter의 pinned=Y 및 best alias 유지 PASS. Admin REST는 변경 범위 밖이며 기존 source·CI로 보존 경계를 확인했다."
},
{
"id": "previous-ota-websocket-activate",
"consumerId": "previous-ota",
"interface": "websocket",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "API #237은 REST presenter와 type/Swagger만 변경한다. WebSocket 코드·인증·wire 계약 불변 및 기존 CI 성공을 보존 근거로 사용한다. 별도 사용자 세션 생성은 하지 않는다."
},
{
"id": "previous-ota-websocket-restore-api",
"consumerId": "previous-ota",
"interface": "websocket",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "API 1a44d374..dabfc71a의 13개 변경 파일에 WebSocket·인증·queue 코드가 없고 기존 handler와 메시지 계약은 byte-equivalent다. CI Core tests 성공을 재사용한다. 새 사용자 WebSocket 세션을 열었다고 주장하지 않는다."
},
{
"id": "previous-ota-bootstrap-activate",
"consumerId": "previous-ota",
"interface": "bootstrap",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
},
{
"id": "previous-ota-bootstrap-restore-api",
"consumerId": "previous-ota",
"interface": "bootstrap",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
},
{
"id": "previous-ota-version-activate",
"consumerId": "previous-ota",
"interface": "version",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "2026-09-05 16:54:49 KST 운영 dabfc71a에서 google/apple build105·107 getSettingList 공개 HTTPS 200·ok=true, min_version107, 105 force_update2/107 force_update0, Store HTTPS 링크 유지 PASS. source의 기존 bootstrap/version 응답 계약은 불변이다."
},
{
"id": "previous-ota-version-restore-api",
"consumerId": "previous-ota",
"interface": "version",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST 운영 google/apple 105·107 getSettingList HTTP 200·ok=true, min_version=107, 105 force_update=2/107=0 PASS."
},
{
"id": "previous-admin-rest-activate",
"consumerId": "previous-admin",
"interface": "rest",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "API 1a44d374..dabfc71a 13파일 diff는 App presenter/type/Swagger와 테스트뿐이며 Admin REST 구현·인가·쓰기 경로는 불변이다. 운영 CMS source 59cb486과 정렬 source 44ca0d1의 차이는 dependency/lockfile뿐이고 package runtime exports는 같다. 기존 Admin 275 tests·CI와 44ca0d1 로컬 production build PASS를 재사용했다. 새 CMS 배포나 인증 사용자 Admin HTTP를 실행한 증빙으로 확대하지 않는다."
},
{
"id": "previous-admin-rest-restore-api",
"consumerId": "previous-admin",
"interface": "rest",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST previous API 1a44d374 운영 HTTP manager/all 6건·manager/detail/16 image slice 4건·이미지 HEAD 5건 200, 실제 lounge list/myList/detail presenter의 pinned=Y 및 best alias 유지 PASS. Admin REST는 변경 범위 밖이며 기존 source·CI로 보존 경계를 확인했다."
},
{
"id": "previous-admin-websocket-activate",
"consumerId": "previous-admin",
"interface": "websocket",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "API #237은 REST presenter와 type/Swagger만 변경한다. WebSocket 코드·인증·wire 계약 불변 및 기존 CI 성공을 보존 근거로 사용한다. 별도 사용자 세션 생성은 하지 않는다."
},
{
"id": "previous-admin-websocket-restore-api",
"consumerId": "previous-admin",
"interface": "websocket",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "API 1a44d374..dabfc71a의 13개 변경 파일에 WebSocket·인증·queue 코드가 없고 기존 handler와 메시지 계약은 byte-equivalent다. CI Core tests 성공을 재사용한다. 새 사용자 WebSocket 세션을 열었다고 주장하지 않는다."
},
{
"id": "current-admin-rest-activate",
"consumerId": "current-admin",
"interface": "rest",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "API 1a44d374..dabfc71a 13파일 diff는 App presenter/type/Swagger와 테스트뿐이며 Admin REST 구현·인가·쓰기 경로는 불변이다. 운영 CMS source 59cb486과 정렬 source 44ca0d1의 차이는 dependency/lockfile뿐이고 package runtime exports는 같다. 기존 Admin 275 tests·CI와 44ca0d1 로컬 production build PASS를 재사용했다. 새 CMS 배포나 인증 사용자 Admin HTTP를 실행한 증빙으로 확대하지 않는다."
},
{
"id": "current-admin-rest-restore-api",
"consumerId": "current-admin",
"interface": "rest",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "2026-09-05 16:16 KST previous API 1a44d374 운영 HTTP manager/all 6건·manager/detail/16 image slice 4건·이미지 HEAD 5건 200, 실제 lounge list/myList/detail presenter의 pinned=Y 및 best alias 유지 PASS. Admin REST는 변경 범위 밖이며 기존 source·CI로 보존 경계를 확인했다."
},
{
"id": "current-admin-websocket-activate",
"consumerId": "current-admin",
"interface": "websocket",
"apiGeneration": "current",
"exposure": "activation",
"expected": "success",
"evidence": "API #237은 REST presenter와 type/Swagger만 변경한다. WebSocket 코드·인증·wire 계약 불변 및 기존 CI 성공을 보존 근거로 사용한다. 별도 사용자 세션 생성은 하지 않는다."
},
{
"id": "current-admin-websocket-restore-api",
"consumerId": "current-admin",
"interface": "websocket",
"apiGeneration": "previous",
"exposure": "rollback",
"expected": "success",
"evidence": "API 1a44d374..dabfc71a의 13개 변경 파일에 WebSocket·인증·queue 코드가 없고 기존 handler와 메시지 계약은 byte-equivalent다. CI Core tests 성공을 재사용한다. 새 사용자 WebSocket 세션을 열었다고 주장하지 않는다."
},
{
"id": "previous-ota-rest-restore-client",
"consumerId": "previous-ota",
"interface": "rest",
"apiGeneration": "current",
"exposure": "rollback",
"expected": "success",
"evidence": "운영 dabfc71a의 2026-09-05 16:54:49 KST 공개 매니저 응답·이미지·설정과 배포 lounge presenter PASS, 기존 2.5.1 source 88a6d851의 canonical 소비 및 불변 WebSocket source·CI로 호환 경계를 확인했다. Store107과 기존 OTA v34/v31을 그대로 유지했으며 실제 client rollback을 실행한 기록은 아니다. 지원 종료 Store105로 내리는 복구는 선택하지 않는다."
},
{
"id": "previous-ota-websocket-restore-client",
"consumerId": "previous-ota",
"interface": "websocket",
"apiGeneration": "current",
"exposure": "rollback",
"expected": "success",
"evidence": "운영 dabfc71a의 2026-09-05 16:54:49 KST 공개 매니저 응답·이미지·설정과 배포 lounge presenter PASS, 기존 2.5.1 source 88a6d851의 canonical 소비 및 불변 WebSocket source·CI로 호환 경계를 확인했다. Store107과 기존 OTA v34/v31을 그대로 유지했으며 실제 client rollback을 실행한 기록은 아니다. 지원 종료 Store105로 내리는 복구는 선택하지 않는다."
},
{
"id": "previous-ota-bootstrap-restore-client",
"consumerId": "previous-ota",
"interface": "bootstrap",
"apiGeneration": "current",
"exposure": "rollback",
"expected": "success",
"evidence": "운영 dabfc71a의 2026-09-05 16:54:49 KST 공개 매니저 응답·이미지·설정과 배포 lounge presenter PASS, 기존 2.5.1 source 88a6d851의 canonical 소비 및 불변 WebSocket source·CI로 호환 경계를 확인했다. Store107과 기존 OTA v34/v31을 그대로 유지했으며 실제 client rollback을 실행한 기록은 아니다. 지원 종료 Store105로 내리는 복구는 선택하지 않는다."
},
{
"id": "previous-ota-version-restore-client",
"consumerId": "previous-ota",
"interface": "version",
"apiGeneration": "current",
"exposure": "rollback",
"expected": "success",
"evidence": "운영 dabfc71a의 2026-09-05 16:54:49 KST 공개 매니저 응답·이미지·설정과 배포 lounge presenter PASS, 기존 2.5.1 source 88a6d851의 canonical 소비 및 불변 WebSocket source·CI로 호환 경계를 확인했다. Store107과 기존 OTA v34/v31을 그대로 유지했으며 실제 client rollback을 실행한 기록은 아니다. 지원 종료 Store105로 내리는 복구는 선택하지 않는다."
}
]
},
"runtimeRecovery": {
"strategy": "previous-release",
"stateSafety": {
"source": "application-evidence",
"persistedState": "1a44d374..dabfc71a는 App 응답 presenter·Swagger·계약 type과 테스트만 변경한다. DB migration·persisted write·설정 변경이 없으므로 같은 DB에서 이전 additive API로 복구한다.",
"queuedState": "같은 diff에 queue·outbox·worker·cron 변경이 없다. 기존 작업의 format·cursor·재시도·idempotency 상태를 변경하지 않는다.",
"externalEffects": "결제·푸시·메일·외부 발송 경로는 byte-equivalent다. smoke는 공개 조회와 순수 함수 호출만 사용하고 사용자 데이터 쓰기나 외부 발송을 실행하지 않는다."
},
"previousReleaseCaseIds": [
"previous-store-rest-restore-api",
"previous-store-websocket-restore-api",
"previous-store-bootstrap-restore-api",
"previous-store-version-restore-api",
"current-store-rest-restore-api",
"current-store-websocket-restore-api",
"current-store-bootstrap-restore-api",
"current-store-version-restore-api",
"previous-ota-rest-restore-api",
"previous-ota-websocket-restore-api",
"previous-ota-bootstrap-restore-api",
"previous-ota-version-restore-api",
"previous-admin-rest-restore-api",
"previous-admin-websocket-restore-api",
"current-admin-rest-restore-api",
"current-admin-websocket-restore-api"
]
}
}
},
"docs": {
"status": "released",
"summary": "실제 API cutover 결과와 v2.5.7 태그를 고정한 최종 기록을 docs v2.5.5로 마감한다. API 운영 결과·현재 구조·완료된 두 호환 부채를 동기화하고 과거 v2.5.4 기록은 보존한다.",
"evidence": {}
}
},
"apiContractCutover": {
"status": "released",
"contractArtifactSync": {
"command": "API package publish workflow·consumer package.json/yarn.lock·각 PR verify/CI·최종 git tree 비교",
"result": "API stable 0.1.43 발행 성공. Admin #125(44ca0d1acfe02cdd205dc188a957781d26746ac2)와 Mobile #265(38185926948846fd04de507376ebb9fb56d83bb1) main 병합·exact pin·설치·CI 완료. Admin 로컬 production build도 성공했다.",
"consumerPath": "기존 Store 2.5.1(107)과 OTA 88a6d851은 profile_image_path/detail_profile/pinned를 이미 소비한다. 신규 source pin과 설치된 binary package를 혼동하지 않는다."
},
"activation": {
"caseIds": [
"previous-store-rest-activate",
"previous-store-websocket-activate",
"previous-store-bootstrap-activate",
"previous-store-version-activate",
"current-store-rest-activate",
"current-store-websocket-activate",
"current-store-bootstrap-activate",
"current-store-version-activate",
"previous-ota-rest-activate",
"previous-ota-websocket-activate",
"previous-ota-bootstrap-activate",
"previous-ota-version-activate",
"previous-admin-rest-activate",
"previous-admin-websocket-activate",
"current-admin-rest-activate",
"current-admin-websocket-activate"
],
"appliedAt": "2026-09-05T07:54:49.879Z (KST 16:54:49)",
"sequenceEvidence": "2026-09-05 출시 책임자가 현재 전제 조사와 cold review 후 운영 배포·문서 병합·정리를 최종 승인하여 종전 2.5.2 초과 출시 연기를 종료했다. 기존 Store107 공개·min107·OTA 유지 → Admin #125·Mobile #265 main 병합 → 개발계 16:21 KST postcheck → docs Draft #215 exact head 132438e9aa3206f024982f43e3c27af8a57031ce·필수 CI3개·release:continue preflight PASS → 기준점 불변 확인 → 운영 16:53:53 KST exact dabfc71a 배포 → 16:54:49 KST case PASS → 바로 다음 Gate에서 API v2.5.7 원격 peeled SHA 일치 → docs 최종화. 전 사용자 업데이트 또는 구버전 요청 0건은 완료 조건에서 제외했다.",
"bootstrapUpgradeEvidence": "운영 배포 전 2026-09-05 16:06·16:16 KST 및 배포 후 16:54:49 KST에 google/apple build105·107의 설정 조회가 성공했다. 양 플랫폼 min_version107, build105 force_update2/build107 force_update0와 Store HTTPS 링크를 그대로 유지했다."
},
"rollback": {
"caseIds": [
"previous-ota-rest-restore-client",
"previous-ota-websocket-restore-client",
"previous-ota-bootstrap-restore-client",
"previous-ota-version-restore-client"
],
"sequenceEvidence": "새 OTA/Store 배포가 없으므로 현재 v34/v31과 Store107을 유지한다. API 회귀가 발생하면 previous-release case가 검증된 1a44d374로 PM2를 복구하며, 정상 작동하는 client를 2.5.0으로 내리지 않는다.",
"cautions": "2.5.0은 최소 지원 build 아래다. rollback은 2.5.1 canonical client와 additive API를 대상으로 하며 과거 schema 변경 이전 API로 되돌리지 않는다."
}
}
}