You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
기존 제목의 PIN 저장 누락 진단은 2026-08-25 댓글에서 정정됐다. 당시 PIN 저장·패스키 인증 사용은 확인됐고 앱 재시작 잠금과 재입력 화면은 없었다. 저장 로직 신설·앱 시작 게이트·확인 재입력 단계 구현 예약은 제거한다.
PM 확인이 필요한 결정
앱 잠금과 패스키의 관계, 잠금 적용 시점, 설정·변경 시 확인 절차, PIN 분실·미설정·취소 시 동작을 PM에게 확인한다. 기존 인증과 저장 동작을 임의로 삭제하지 않는다.
완료 기준
PM의 명시적인 답변과 적용 범위·근거 링크를 기록한다. 답변 전에는 구현·재개·테스트 완료 체크리스트를 예약하지 않는다. 결정 후 최신 코드와 계약을 대조해 실제 필요한 작업만 정의한다. 디자이너에게 질문하거나 태그하지 않으며, 미답변이나 과거 FE 재량 위임을 승인으로 해석하지 않는다.
정리 근거
2026-09-13 사용자 요청에 따라 미확정 구현 예약을 제거했다. 기능 구현 완료를 의미하지 않는다. 기존 댓글의 실측은 참고 자료이며, 상충하는 옛 구현 지시는 현재 범위를 대체하지 않는다.
2026-08-29T11:25:43Z 에 시안 댓글 1905234302 으로 나간 질문(앵커 노드 1119:12444)에 류하늬가 2026-09-03T18:11:09Z 에 답글 1912574508 로 답했고, 그 시안이 정본 페이지에 실제로 들어와 있다. 설정 구역 4327:99449 안의 새 섹션 4832:57442 다. 아래 노드는 오늘 Figma MCP 로 실재와 문구를 확인했다.
지문 일러스트와 "본인 인증 후 비밀번호 재설정이 가능합니다.", 버튼은 "사용자 인증하기"
확인 재입력 화면은 이번에 새로 온 것이 아니라 전부터 있었다. 4327:65094 · 4327:65154 의 "비밀번호를 다시 한 번 입력해 주세요." 다. 2026-08-25 코멘트가 미구현으로 적은 두 가지 중 설정 시 확인 재입력은 시안이 있었고, 이번에 복구 경로 그림이 추가됐다.
이것은 디자이너 답이지 PM 승인이 아니다
이 이슈의 완료 기준은 PM 의 명시적 답변과 적용 범위·근거 링크다. 오늘 도착한 것은 디자이너의 시안이다. 화면이 그려졌다는 사실이 제품 정책을 정하지는 않으므로 이 코멘트를 승인 근거로 삼아 착수하지 않는다.
남은 미결 (PM)
출시 범위. 앱 잠금을 이번 출시에 넣는지가 정해져 있지 않다. 시안이 있다는 것은 범위 확정이 아니다.
본인 인증의 실제 수단. 시안은 지문 일러스트와 "사용자 인증하기" 버튼까지만 정한다. 계정 재로그인인지 기기 생체 인증인지에 따라 구현도 실패 처리도 통째로 달라진다. 앱은 이미 같은 PIN 을 패스키 등록의 "비밀번호로 인증하기" 에서 쓰고 있다(2026-08-25 코멘트).
잠금이 걸리는 시점. 콜드 스타트만인지, 백그라운드 복귀도 포함인지, 포함이면 유예 시간이 얼마인지. 시안에는 없다.
29일째 답이 없는 질문이 따로 있다
2026-08-15T12:52:20Z 댓글 1886384849 의 앱 잠금과 패스키의 관계 질문은 오늘까지 29일 무응답이다. 위 1912574508 은 0829 질문에 달린 답글이라 이 스레드를 대신하지 않는다.
그 질문의 발신자는 이 이슈 담당자가 아니라 박경민(minii7582)이다. 다음 세션이 자기가 보낸 질문이 무시된 것으로 읽고 재촉을 중복해 올리지 않도록 적어 둔다.
develop 실측: PIN 은 저장되지 않는다 (origin/develop 7d87aa3f4, 2026-09-13)
오늘 올린 시안 코멘트와 별개로, 본문과 옛 코멘트가 develop 실태와 어긋나는 부분을 실측해 둔다. PM 답을 기다리는 동안 다음 착수자가 "저장은 되어 있으니 게이트와 재입력만 하면 된다"는 전제로 시작하는 것을 막기 위한 기록이다. 구현은 하지 않았고 완료 기준도 그대로다.
1. 본문 정정: PIN 을 저장하는 코드가 없다
본문의 "당시 PIN 저장·패스키 인증 사용은 확인됐고"와 "저장 로직 신설 ... 예약은 제거한다"는 사실이 아닌 전제 위에 서 있다. develop 어디에도 PIN 을 보관하는 경로가 없다.
core/datastore/src/main/java/com/afternote/core/datastore/UserProfileDataSource.kt:30-33 의 Keys 는 user_name 과 is_passkey_registered 둘뿐이다. PIN 을 담는 Preferences 키가 없다.
EncryptedSharedPreferences 는 저장소 전체에서 0건이다.
AppLockSetupViewModel.kt:12-14 는 @Inject constructor() 로 생성자 인자가 없다. PIN 은 MutableStateFlow 에만 있고 resetPin() 이 지운다(:35-37). DataSource·Repository 의존이 하나도 없다.
SettingNavGraph.kt:192 가 onPinComplete = { actions.onAppLockBack() } 라 화면에서 넘어온 pin 을 그대로 버린다.
feature/setting/data 에는 소스가 없다. src/main 아래가 AndroidManifest.xml 하나다.
한 가지 덧붙인다. Keystore 자체는 저장소에 한 곳 있다. feature/afternote/presentation/src/main/kotlin/com/afternote/feature/afternote/presentation/shared/fingerprint/BiometricCryptoGate.kt:14 의 alias afternote_biometric_gate 다. 다만 이건 고정 평문(:24 의 CRYPTO_CHALLENGE)을 돌려 인증 성사 여부만 보는 열람 게이트이고, 같은 파일 :44 가 "보관 중인 암호문이 없어"라고 적어 두었다. PIN 보관처가 아니다.
따라서 PM 답이 온 뒤 필요한 작업은 본문이 남긴 둘(앱 시작 게이트, 확인 재입력)이 아니라 셋이다. 저장이 그대로 남아 있다.
2. 2026-08-25 의 "PIN 저장 정상"은 검증 부재가 만든 오탐
그 코멘트는 패스키 등록의 "비밀번호로 인증하기"에 같은 1234 가 통과한 것을 저장·조회의 증거로 읽었다. 그 화면에는 비교 대상이 없다.
PassKeyPasswordScreen.kt:25-31 은 uiState.isComplete, 즉 4자리가 차는 즉시 passKeyViewModel.savePasskeyRegistered() 를 부르고 화면을 넘긴다. 저장된 값과 대조하는 코드가 없다. 아무 4자리나 통과한다.
그 코멘트가 지목한 커밋 4e0a648eb 의 같은 파일도 동일했다(:38-42). 그날의 통과는 조회 성공이 아니라 검증 부재의 결과다.
같은 표의 나머지 두 줄("앱 시작 시 잠금 진입 ❌", "설정 시 확인 재입력 ❌")은 오늘도 사실이다.
3. 오늘 코멘트의 PM 질문 2번에 붙일 한 줄
오늘 코멘트의 미결 2번에서 "앱은 이미 같은 PIN 을 패스키 등록의 비밀번호로 인증하기에서 쓰고 있다"고 적었는데, 그 근거가 위 오탐이었다. 정정한다. 지금 앱에는 대조할 비밀값이 아예 없으므로 새 복구 시안의 본인 인증하기도, 기존 패스키의 비밀번호로 인증하기(PassKeyMakingScreen.kt:38,103 → SettingNavGraph.kt:178 → PasskeyPasswordRoute, 버튼 문구는 PassKeyMakingContent.kt:84)도 오늘은 검증 대상이 없다. 본인 인증 수단을 무엇으로 정하든 대조할 값을 새로 만드는 일이 함께 붙는다. 같은 결정에 묶인 #574 와 함께 물어야 한다.
4. 1~3자리 이탈은 그대로 살아 있다
2026-08-22 코멘트의 재현은 develop 에 유효하다. 다만 그 뒤 줄 번호가 움직였다.
NumberKeypad.kt:52-57 이 PIN 길이와 무관하게 "확인" 키에서 onConfirmClick() 을 부른다(그때와 같은 :55).
AppLockSetupScreen.kt:36 이 onConfirmClick = { currentOnPinComplete(uiState.pin) } 로 길이 검사 없이 넘긴다(그때 :48).
SettingNavGraph.kt:192 가 받은 pin 을 버리고 pop 한다(그때 :179).
그 코멘트의 "#572 수정 PR 에서 회귀 테스트로 추가한다"는 예약은 2026-09-13 본문 개편(답변 전 구현·테스트 체크리스트 예약 금지)과 충돌하므로 승계하지 않는다.
5. 확인 재입력·변경 단계는 프로덕션에서 도달 불가
PinSetupStep.CONFIRM_NEW 와 ENTER_CURRENT 는 타입으로만 존재한다. 소비처가 AppLockSetupContent.kt:36-38 의 when 분기와 같은 파일 Preview(:71-108), 그리고 AppLockSetupScreenScreenshotTest.kt:21,28,35 뿐이다. SettingNavGraph.kt:191 이 step = PinSetupStep.ENTER_NEW 를 하드코딩하고, SettingRoute.kt:52 의 AppLockSetupRoute 는 data object 라 step 파라미터를 받을 자리가 없다. 시안이 전부터 있었다는 점은 오늘 코멘트에 적은 대로다.
6. 앱 시작 잠금 게이트는 app 모듈에 없다
app/src/main/java/com/afternote/afternote_fe 아래 게이트는 update/ForceUpdateGate.kt 하나뿐이다. 설정 화면의 비밀번호 변경 진입도 SettingNavGraph.kt:46 에서 onPasswordChangeClick = {} 로 비어 있다.
7. 착수 시점 주의: 파일 경로가 바뀌어 있을 것이다
열린 PR 62건 본문에 Closes #572 는 0건이라 중복 착수 위험은 없다. 대신 대상 파일이 열린 refactor 스택에 물려 있다.
PM 답이 온 뒤 구현하는 사람은 위 경로 이동을 전제해야 한다. 이 코멘트의 줄 번호는 7d87aa3f4 기준이다.
#2013(#1166)은 BiometricCryptoGate 를 core/common 으로 올리고 PassKeyMakingScreen.kt 의 지문 인증을 암호 연산으로 바꾸는 PR 이라 앱 잠금 PIN 파일들과는 겹치지 않는다. 다만 PM 이 본인 인증 수단을 기기 생체 인증으로 정하면 그 PR 이 만든 게이트가 곧 재료가 된다.
본문은 고치지 않았다
본문의 어긋난 문장은 남은 작업을 좁히는 쪽이 아니라 넓히는 쪽이고, 완료 기준(PM 의 명시적 답변과 근거 링크 기록)은 그대로다. 본문 편집 대신 이 코멘트로 정정을 남긴다.
Activity
OnlyReadOneBook commentedon Aug 22, 2026
Android Managed Device 재현 보강 (2026-08-22)
#840의 현재 구현 경로 androidTest 감사 중 이 이슈와 같은 원인의 추가 경계를 Pixel 2 / API 30 Gradle Managed Device에서 재현했습니다.
재현
1한 자리만 입력확인선택결과
A one-digit PIN must not leave app-lock setup현재 원인 경로
NumberKeypad.kt:55: PIN 길이와 무관하게 확인 키가onConfirmClick()호출AppLockSetupScreen.kt:48: 확인 시currentOnPinComplete(uiState.pin)을 즉시 호출SettingNavGraph.kt:179: 전달된 PIN을 저장하지 않고onAppLockBack()으로 화면만 pop기존 4자리 PIN 저장 누락뿐 아니라 1~3자리 PIN도 확인 키로 화면을 이탈할 수 있으므로, 수정 시 확인 키 활성 조건 또는 화면 측 길이 검증과 저장/확인 단계를 함께 회귀 검증해야 합니다.
OnlyReadOneBook commentedon Aug 25, 2026
재현 확인 — 다만 본문의 원인 진단이 오진입니다 (develop
4e0a648eb, 2026-08-25 17:04 KST)증상은 그대로 재현됩니다.
1234) → 확인 재입력 없이 즉시 완료, 성공 안내도 없음그런데 PIN 은 저장되고 있습니다
이어서 설정 → 패스키 관리 → 패스키 등록 → "비밀번호로 인증하기" 에 같은
1234를 넣었더니 인증이 통과했습니다. 즉 PIN 은 정상적으로 저장·조회되고 있습니다.본문의 "입력한 PIN 이 저장되지 않아 재시작해도 잠금 없음" 에서 앞부분이 사실과 다릅니다. 수정 범위는 저장 로직이 아니라 앱 시작 시 잠금 게이트 진입과 설정 시 확인 재입력 단계 두 가지입니다.
관련 — "비밀번호로 인증하기" 가 실제로 요구하는 값이 이 앱 잠금 PIN 이라는 점은 #574 에 따로 적었습니다.
docs(qa): 로그인 상태 설정 구간 실측 결과를 반영한다
[-]fix(setting): 앱 잠금 PIN 이 저장되지 않아 잠금 미적용 — 입력값을 버리고 화면만 닫음[/-][+]앱 잠금 PIN 이 저장되지 않아 잠금 미적용 — 입력값을 버리고 화면만 닫음[/+][-]앱 잠금 PIN 이 저장되지 않아 잠금 미적용 — 입력값을 버리고 화면만 닫음[/-][+]앱 잠금의 적용 시점·PIN 확인·복구 정책을 PM에게 확인한다[/+]OnlyReadOneBook commentedon Sep 13, 2026
디자이너 답이 도착했다 (2026-09-13 확인)
2026-08-29T11:25:43Z 에 시안 댓글 1905234302 으로 나간 질문(앵커 노드 1119:12444)에 류하늬가 2026-09-03T18:11:09Z 에 답글 1912574508 로 답했고, 그 시안이 정본 페이지에 실제로 들어와 있다. 설정 구역 4327:99449 안의 새 섹션 4832:57442 다. 아래 노드는 오늘 Figma MCP 로 실재와 문구를 확인했다.
확인 재입력 화면은 이번에 새로 온 것이 아니라 전부터 있었다. 4327:65094 · 4327:65154 의 "비밀번호를 다시 한 번 입력해 주세요." 다. 2026-08-25 코멘트가 미구현으로 적은 두 가지 중 설정 시 확인 재입력은 시안이 있었고, 이번에 복구 경로 그림이 추가됐다.
이것은 디자이너 답이지 PM 승인이 아니다
이 이슈의 완료 기준은 PM 의 명시적 답변과 적용 범위·근거 링크다. 오늘 도착한 것은 디자이너의 시안이다. 화면이 그려졌다는 사실이 제품 정책을 정하지는 않으므로 이 코멘트를 승인 근거로 삼아 착수하지 않는다.
남은 미결 (PM)
29일째 답이 없는 질문이 따로 있다
2026-08-15T12:52:20Z 댓글 1886384849 의 앱 잠금과 패스키의 관계 질문은 오늘까지 29일 무응답이다. 위 1912574508 은 0829 질문에 달린 답글이라 이 스레드를 대신하지 않는다.
그 질문의 발신자는 이 이슈 담당자가 아니라 박경민(minii7582)이다. 다음 세션이 자기가 보낸 질문이 무시된 것으로 읽고 재촉을 중복해 올리지 않도록 적어 둔다.
OnlyReadOneBook commentedon Sep 13, 2026
develop 실측: PIN 은 저장되지 않는다 (origin/develop
7d87aa3f4, 2026-09-13)오늘 올린 시안 코멘트와 별개로, 본문과 옛 코멘트가 develop 실태와 어긋나는 부분을 실측해 둔다. PM 답을 기다리는 동안 다음 착수자가 "저장은 되어 있으니 게이트와 재입력만 하면 된다"는 전제로 시작하는 것을 막기 위한 기록이다. 구현은 하지 않았고 완료 기준도 그대로다.
1. 본문 정정: PIN 을 저장하는 코드가 없다
본문의 "당시 PIN 저장·패스키 인증 사용은 확인됐고"와 "저장 로직 신설 ... 예약은 제거한다"는 사실이 아닌 전제 위에 서 있다. develop 어디에도 PIN 을 보관하는 경로가 없다.
core/datastore/src/main/java/com/afternote/core/datastore/UserProfileDataSource.kt:30-33의Keys는user_name과is_passkey_registered둘뿐이다. PIN 을 담는 Preferences 키가 없다.EncryptedSharedPreferences는 저장소 전체에서 0건이다.AppLockSetupViewModel.kt:12-14는@Inject constructor()로 생성자 인자가 없다. PIN 은MutableStateFlow에만 있고resetPin()이 지운다(:35-37). DataSource·Repository 의존이 하나도 없다.SettingNavGraph.kt:192가onPinComplete = { actions.onAppLockBack() }라 화면에서 넘어온 pin 을 그대로 버린다.feature/setting/data에는 소스가 없다.src/main아래가AndroidManifest.xml하나다.한 가지 덧붙인다. Keystore 자체는 저장소에 한 곳 있다.
feature/afternote/presentation/src/main/kotlin/com/afternote/feature/afternote/presentation/shared/fingerprint/BiometricCryptoGate.kt:14의 aliasafternote_biometric_gate다. 다만 이건 고정 평문(:24의CRYPTO_CHALLENGE)을 돌려 인증 성사 여부만 보는 열람 게이트이고, 같은 파일:44가 "보관 중인 암호문이 없어"라고 적어 두었다. PIN 보관처가 아니다.따라서 PM 답이 온 뒤 필요한 작업은 본문이 남긴 둘(앱 시작 게이트, 확인 재입력)이 아니라 셋이다. 저장이 그대로 남아 있다.
2. 2026-08-25 의 "PIN 저장 정상"은 검증 부재가 만든 오탐
그 코멘트는 패스키 등록의 "비밀번호로 인증하기"에 같은
1234가 통과한 것을 저장·조회의 증거로 읽었다. 그 화면에는 비교 대상이 없다.PassKeyPasswordScreen.kt:25-31은uiState.isComplete, 즉 4자리가 차는 즉시passKeyViewModel.savePasskeyRegistered()를 부르고 화면을 넘긴다. 저장된 값과 대조하는 코드가 없다. 아무 4자리나 통과한다.4e0a648eb의 같은 파일도 동일했다(:38-42). 그날의 통과는 조회 성공이 아니라 검증 부재의 결과다.같은 표의 나머지 두 줄("앱 시작 시 잠금 진입 ❌", "설정 시 확인 재입력 ❌")은 오늘도 사실이다.
3. 오늘 코멘트의 PM 질문 2번에 붙일 한 줄
오늘 코멘트의 미결 2번에서 "앱은 이미 같은 PIN 을 패스키 등록의 비밀번호로 인증하기에서 쓰고 있다"고 적었는데, 그 근거가 위 오탐이었다. 정정한다. 지금 앱에는 대조할 비밀값이 아예 없으므로 새 복구 시안의 본인 인증하기도, 기존 패스키의 비밀번호로 인증하기(
PassKeyMakingScreen.kt:38,103→SettingNavGraph.kt:178→PasskeyPasswordRoute, 버튼 문구는PassKeyMakingContent.kt:84)도 오늘은 검증 대상이 없다. 본인 인증 수단을 무엇으로 정하든 대조할 값을 새로 만드는 일이 함께 붙는다. 같은 결정에 묶인 #574 와 함께 물어야 한다.4. 1~3자리 이탈은 그대로 살아 있다
2026-08-22 코멘트의 재현은 develop 에 유효하다. 다만 그 뒤 줄 번호가 움직였다.
NumberKeypad.kt:52-57이 PIN 길이와 무관하게 "확인" 키에서onConfirmClick()을 부른다(그때와 같은:55).AppLockSetupScreen.kt:36이onConfirmClick = { currentOnPinComplete(uiState.pin) }로 길이 검사 없이 넘긴다(그때:48).SettingNavGraph.kt:192가 받은 pin 을 버리고 pop 한다(그때:179).그 코멘트의 "#572 수정 PR 에서 회귀 테스트로 추가한다"는 예약은 2026-09-13 본문 개편(답변 전 구현·테스트 체크리스트 예약 금지)과 충돌하므로 승계하지 않는다.
5. 확인 재입력·변경 단계는 프로덕션에서 도달 불가
PinSetupStep.CONFIRM_NEW와ENTER_CURRENT는 타입으로만 존재한다. 소비처가AppLockSetupContent.kt:36-38의when분기와 같은 파일 Preview(:71-108), 그리고AppLockSetupScreenScreenshotTest.kt:21,28,35뿐이다.SettingNavGraph.kt:191이step = PinSetupStep.ENTER_NEW를 하드코딩하고,SettingRoute.kt:52의AppLockSetupRoute는data object라 step 파라미터를 받을 자리가 없다. 시안이 전부터 있었다는 점은 오늘 코멘트에 적은 대로다.6. 앱 시작 잠금 게이트는 app 모듈에 없다
app/src/main/java/com/afternote/afternote_fe아래 게이트는update/ForceUpdateGate.kt하나뿐이다. 설정 화면의 비밀번호 변경 진입도SettingNavGraph.kt:46에서onPasswordChangeClick = {}로 비어 있다.7. 착수 시점 주의: 파일 경로가 바뀌어 있을 것이다
열린 PR 62건 본문에
Closes #572는 0건이라 중복 착수 위험은 없다. 대신 대상 파일이 열린 refactor 스택에 물려 있다.AppLockSetup*·PinSetupStep이presentation/applock/으로,PassKey*가presentation/passkey/로,NumberKeypad.kt가presentation/shared/component/로 이동setting_접두사NumberKeypad.kt타이포그래피 수정PM 답이 온 뒤 구현하는 사람은 위 경로 이동을 전제해야 한다. 이 코멘트의 줄 번호는
7d87aa3f4기준이다.#2013(#1166)은
BiometricCryptoGate를core/common으로 올리고PassKeyMakingScreen.kt의 지문 인증을 암호 연산으로 바꾸는 PR 이라 앱 잠금 PIN 파일들과는 겹치지 않는다. 다만 PM 이 본인 인증 수단을 기기 생체 인증으로 정하면 그 PR 이 만든 게이트가 곧 재료가 된다.본문은 고치지 않았다
본문의 어긋난 문장은 남은 작업을 좁히는 쪽이 아니라 넓히는 쪽이고, 완료 기준(PM 의 명시적 답변과 근거 링크 기록)은 그대로다. 본문 편집 대신 이 코멘트로 정정을 남긴다.
OnlyReadOneBook commentedon Sep 18, 2026
PM 결정 대기 항목은 깃허브 이슈로 두지 않고 피그마 질문 한 자리에만 둔다(2026-09-18 결정). 이 이슈의 질문은 피그마 스레드에 걸려 있다: https://www.figma.com/design/UP9ZR186jHvRBicjA2SOea/?node-id=4327-64956#1932490741 (#765·#574 와 합쳐 하나로 물었다.) 답이 오면 그 답을 근거로 구현 이슈를 새로 만든다.