Skip to content

fix(core-ui,app): 다크 팔레트 확정까지 팔레트·시스템바를 라이트로 잠근다 (#1873) - #1723

Merged
Sadturtleman merged 5 commits into
developfrom
fix/1719-lock-light-theme
Sep 4, 2026
Merged

Sadturtleman merged 5 commits into
developfrom
fix/1719-lock-light-theme

Conversation

@Sadturtleman

@Sadturtleman Sadturtleman commented Sep 2, 2026 •

Copy link
Copy Markdown
Collaborator

📌𝘐𝘴𝘴𝘶𝘦𝘴

📎𝘞𝘰𝘳𝘬 𝘋𝘦𝘴𝘤𝘳𝘪𝘱𝘵𝘪𝘰𝘯

판정: 지원 여부를 정하기 전에 «중간 상태» 부터 끊는다

이슈가 「지원한다 / 지원하지 않는다」 중 하나를 정하라고 했고, 디자인 확정 전이라면 라이트로 먼저 막는 편이 안전하다고 적어 뒀습니다. 그 임시 조치만 반영합니다.

지금 상태가 양쪽 끝보다 나쁩니다. 다크 팔레트는 물리는데 화면이 따라오지 않아서, 다크모드 사용자가 앱을 열면 헤더부터 읽히지 않습니다.

자리 지금
「마음의 기록」 헤더 검정 배경에 검정 글자
주간 요약 카드 배경만 밝게 남고 라벨이 저대비

원인은 이슈가 짚은 그대로입니다 — 색을 토큰이 아니라 코드에 박은 자리가 반전을 따라가지 못합니다 (feature/mindrecord/presentation main 에만 29곳).

다크 지원을 버리는 변경이 아닙니다

AfternoteTheme 의 isDarkTheme 기본값만 끊었습니다.

  • darkColors() 와 isDarkTheme 파라미터는 그대로입니다. 값을 넘기면 지금도 다크로 그립니다.
  • 시안 팔레트가 확정되고 하드코딩 색 29곳이 토큰으로 옮겨지면 기본값을 isSystemInDarkTheme() 으로 되돌리면 됩니다. 되돌릴 자리와 조건을 KDoc 에 적었습니다.

이슈는 닫지 않고 Refs 로 걸었습니다. 「지원할 것인가」 판정과 토큰 이관은 남아 있습니다.

가드

잠금이 조용히 풀리는 것을 막습니다.

  • night 한정자에서도 라이트 팔레트인가
  • notnight 에서도 라이트 팔레트인가
  • 명시로 넘기면 여전히 다크인가 — 되돌릴 길이 살아 있는지를 함께 봅니다

Production visibility

  • src/main·src/debug·src/release 공개 범위는 프로덕션 사용처만으로 정했고, 테스트 직접 접근을 이유로 넓히지 않았습니다.
  • 새로 만들거나 수정한 선언은 같은 파일 private → 같은 모듈 internal → 다른 모듈 public 순으로 최소 범위를 확인했습니다.
  • 테스트 seam이 필요하면 공개 프로덕션 API 대신 공개 동작·test fixture·테스트 소스셋을 사용했습니다.
  • explicit API warning/strict 진단과 visibility Konsist 결과를 확인하고, 예외라면 생성 코드·프레임워크 근거를 변경 근처에 남겼습니다.

새 선언이 없습니다. 기존 파라미터의 기본값 한 줄과 KDoc 만 바뀝니다. 가드는 이미 공개된 AfternoteTheme 과 AfternoteDesign.colors.isLightMode 로만 판정해서 seam 을 새로 열지 않았습니다.

🧪 CI Test Plan

{
  "androidTest": {
    "mode": "selected",
    "reason": "MainActivity 의 edge-to-edge 호출과 테마 리소스가 바뀌어 Android 런타임 경계에 걸린다. 실기에서 볼 것은 «시스템바 스타일을 라이트로 고정한 뒤에도 앱이 그대로 뜨고 첫 화면이 읽히는가» 하나라, 기동 경로와 접근성 대비를 실제로 태우는 두 클래스를 고른다. 팔레트 판정 자체는 Robolectric night/notnight 로 JVM 에서 재현되므로 full 은 과하다. 접근성 스모크는 @SdkSuppress(minSdkVersion = 34) 라 api30 lane 에서는 필터에 걸러져 결과 XML 이 남지 않으므로 api34 lane 으로 돌린다.",
    "tests": [
      {
        "path": "app/src/androidTest/java/com/afternote/afternote_fe/AccessibilitySmokeAndroidTest.kt",
        "selector": "com.afternote.afternote_fe.AccessibilitySmokeAndroidTest#welcomeAndLogin_haveNoAutomatedAccessibilityErrors",
        "device": "api34"
      },
      {
        "path": "app/src/androidTest/java/com/afternote/afternote_fe/AppOnboardingCanaryTest.kt",
        "selector": "com.afternote.afternote_fe.AppOnboardingCanaryTest#coldStartWithoutSession_opensLoginFromWelcome",
        "device": "api30"
      },
      {
        "path": "app/src/androidTest/java/com/afternote/afternote_fe/AppOnboardingCanaryTest.kt",
        "selector": "com.afternote.afternote_fe.AppOnboardingCanaryTest#loginInput_survivesActivityRecreation",
        "device": "api30"
      }
    ]
  }
}

📷𝘚𝘤𝘳𝘦𝘦𝘯𝘴𝘩𝘰𝘵

  • 라이트 모드 렌더는 바뀌지 않습니다. 다크모드에서 라이트 팔레트로 그리는 것이 이 PR 의 의도된 변화입니다.

💬𝘛𝘰 𝘙𝘦𝘷𝘪𝘦𝘸𝘦𝘳𝘴

모든 화면이 지나는 테마라 저장소 전체 단위 테스트를 돌렸습니다.

역검증했습니다. 기본값을 isSystemInDarkTheme() 으로 되돌리면 「시스템이 다크여도 기본값은 라이트 팔레트다」가 FAILED 로 돌아섭니다.

🤖 Generated with Claude Code

https://claude.ai/code/session_014bzKzp4MGtVAqPFRxLE7zC

AfternoteTheme 의 isDarkTheme 기본값을 isSystemInDarkTheme() 에서 false 로 바꾼다.

배선만 있고 화면이 안 맞춰진 중간 상태가 양쪽 끝보다 나빴다. 실측에서 「마음의 기록」
헤더가 검정 배경에 검정 글자로 거의 보이지 않았고, 주간 요약 카드는 배경만 밝은 채로
남아 라벨이 저대비로 흐려졌다. 색을 토큰이 아니라 코드에 박은 자리가 반전을 따라가지
못해서다 — feature/mindrecord/presentation main 에만 29곳이다.

다크 지원을 버리는 것이 아니다. darkColors() 와 isDarkTheme 파라미터는 그대로 두고
기본값만 끊었다. 값을 넘기면 지금도 다크로 그릴 수 있고, 시안 팔레트가 확정되고
하드코딩 색이 토큰으로 옮겨지면 기본값을 되돌리면 된다.

가드 3건을 세웠다. night 한정자에서도 라이트인지, notnight 에서도 라이트인지,
명시로 넘기면 여전히 다크인지를 각각 본다. 잠금이 조용히 풀리는 것을 막는다.

역검증: 기본값을 isSystemInDarkTheme() 으로 되돌리면 「시스템이 다크여도 기본값은
라이트 팔레트다」가 FAILED.

전체 단위 테스트 1107건 중 실패 4건은 ci-expected-failures.json 에 등재된
TimeLetterDtoContractTest (#790·#873) 로 이 변경과 무관하다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014bzKzp4MGtVAqPFRxLE7zC

@1hyok 1hyok left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

첫 리뷰 — 팔레트 잠금 자체는 정확하고 되돌리기 쉬운 한 플래그입니다. 다만 enableEdgeToEdge() 가 여전히 시스템 다크를 따라가, 다크 기기에서 상태바·내비바 아이콘이 라이트 배경 위 흰색으로 사라지는 새 회귀가 생겨 변경을 요청합니다.

지적

  1. [blocking] 시스템바 아이콘이 잠기지 않아 다크 기기에서 새 회귀 — app/src/main/java/com/afternote/afternote_fe/MainActivity.kt:27 (diff 밖). 무인자 enableEdgeToEdge() 는 SystemBarStyle.auto 라 uiMode == NIGHT_YES 면 isAppearanceLightStatusBars/NavigationBars = false 로 흰 아이콘을 고릅니다. 이 PR 로 Compose 는 라이트 팔레트의 Scaffold(containerColor = gray1) = #FAFAFA 를 상태바 밑까지 그리므로(AppNavigation.kt:76), 다크 기기(adb shell cmd uimode night yes)에서 모든 화면의 시계·배터리·제스처 바가 #FAFAFA 위 흰색으로 안 보입니다. 종전엔 gray1 이 다크 배경이라 읽혔습니다. 처방 한 줄: enableEdgeToEdge(statusBarStyle = SystemBarStyle.light(TRANSPARENT, TRANSPARENT), navigationBarStyle = SystemBarStyle.light(TRANSPARENT, TRANSPARENT)) — 되돌릴 때 함께 되돌릴 자리라 Theme.kt KDoc 에 병기해 주세요. app 은 제 담당 모듈이지만 이 PR 이 만드는 회귀라 이 PR 에 함께 넣는 것이 맞습니다. DebugSettingsActivity.kt:33 도 같은 패턴(debug 전용).
  2. [normal] 스플래시가 다크 기기에서 #FAFAFA 배경 + 흰 시스템바 아이콘 — app/src/main/res/values/themes.xml:8 (diff 밖, develop 부터). Theme.Afternotefe.Starting 이 Theme.SplashScreen(DayNight) 을 상속해 night 에선 isLightTheme=false 인데 배경은 splash_background #FAFAFA 고정입니다. 이 PR 의 회귀는 아니지만 «라이트 잠금» 일관성 항목 — android:windowLightStatusBar=true(+windowLightNavigationBar) 또는 후속 이슈.
  3. [nit] @Config(sdk=[35]) 가 클래스·메서드에 중복 → ThemeDarkModeLockTest.kt:26 인라인.
  4. [nit] Theme.kt:4 import isSystemInDarkTheme 는 이제 KDoc 링크로만 쓰인다 — 되돌리기용이면 그대로 두셔도 됩니다.

검증

  • CI fail 0 (head 8b5f0b1, 제출 직전 재확인). 검증기 mode=none 통과. 제목·Refs #1719 게이트 통과(지원 여부 판정이 미결이라 Refs 가 맞습니다).
  • 잠금 지점 대조: Compose 팔레트 잠김(이 PR) / XML Activity 테마는 이미 Theme.Material.Light / values-night 없음 / setDefaultNightMode 없음 / ModalBottomSheet 창은 contentColor.isDark() 기준이라 일관 / 프리뷰·골든에 다크 변형 없음(Screenshot 초록). 남는 건 1·2번뿐입니다.
  • 외부 호출처는 AfternoteNavGraphTheme.kt:14,23 뿐이고 둘 다 기본값이라 잠금이 전 화면에 걸립니다. 그 KDoc 의 «라이트 강제» 는 종전엔 거짓이었고 이 PR 로 참이 됩니다.
  • 시안 대조: 해당 없음(팔레트 선택만). 실기동: 미수행 — 1번은 activity 라이브러리 소스로 확정했고, 시각 확인은 다크 기기에서 상태바 한 번이면 됩니다.

* 되돌릴 때는 하드코딩 색 29곳을 토큰으로 옮긴 뒤 이 테스트도 같이 고쳐야 한다.
*/
@RunWith(RobolectricTestRunner::class)
@Config(sdk = [35])

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[nit] 클래스 @Config(sdk=[35]) 와 메서드 @Config(sdk=[35], qualifiers=…) 의 sdk 가 중복입니다 — 메서드엔 qualifiers 만 둬도 병합됩니다. 무해합니다.

@github-actions github-actions Bot added the awaiting-author 변경요청 뒤 작성자 조치 없음 — 공은 작성자에게 있다 label Sep 2, 2026
@1hyok

1hyok commented Sep 2, 2026

Copy link
Copy Markdown
Collaborator

PR #1749(#1748) 가 방금 develop 에 들어갔습니다. PR 제목의 대표 Issue 는 이제 본문에서 Closes(또는 Fixes/Resolves)로만 연결됩니다 — Refs 로는 대표 Issue 를 걸 수 없습니다. 이 PR 은 다음 push 나 본문 수정 때 Repository Quality 가 실패합니다. 미리 알려 드립니다.

이 PR 은 제목 (#1719) 에 본문이 - Refs #1719 입니다.

고치는 방법은 둘 중 하나입니다.

  1. 이 PR 이 그 Issue 를 끝낸다면 본문의 Refs #N 을 Closes #N 으로 바꾸면 끝입니다. 본문 수정만으로 검증이 다시 돕니다.
  2. Issue 의 일부만 한다면 이 PR 이 하는 몫을 새 Issue 로 분리해 그 번호를 제목 (#N) 과 본문 Closes #N 에 넣고, 원래 Issue 는 Refs #원래번호 로 남겨 두면 됩니다. 남는 몫은 원래 Issue 가 계속 추적합니다.

대표 Issue 에 열린 blocked_by 가 있어 Refs 로 두셨던 거라면, 선행 PR 위에 스택하거나 관계가 낡았으면 정리하는 쪽이 맞습니다. 불편을 드려 죄송합니다 — 필요하시면 제가 분리를 도와 드리겠습니다.

팔레트만 잠그니 다크 기기에서 새 회귀가 났다. 무인자 enableEdgeToEdge() 는
SystemBarStyle.auto 라 uiMode == NIGHT_YES 에서 흰 아이콘을 고르는데, Compose 는
이제 라이트 팔레트의 gray1(#FAFAFA) 을 상태바 밑까지 그린다. 밝은 배경 위에 흰
시계·배터리·제스처 바가 얹혀 모든 화면에서 보이지 않는다.

- app 에 enableLightEdgeToEdge() 를 세우고 MainActivity·DebugSettingsActivity 를
  거기로 모은다. 되돌릴 자리를 한 곳으로 만든다.
- 스플래시도 같은 이유로 어긋나 있었다. Theme.SplashScreen 이 DayNight 라 night
  에서 isLightTheme=false 인데 배경은 #FAFAFA 고정이다. windowLightStatusBar·
  windowLightNavigationBar 를 켠다. 이 PR 의 회귀는 아니지만 같은 잠금의 일부다.
- Theme.kt KDoc 에 되돌릴 자리 셋을 병기한다.
- 무인자 호출이 다시 스며드는 것을 konsist 로 막는다. 새 Activity 를 만들 때 손이
  먼저 기억하는 형태가 그쪽이다.

리뷰 nit 반영: ThemeDarkModeLockTest 의 메서드 @config 에서 클래스와 중복인 sdk 제거.

역검증: DebugSettingsActivity 를 무인자 호출로 되돌리면 konsist 가드가 FAILED.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@1hyok 1hyok left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

재리뷰 — 지적 4건이 모두 닫혔고, 요청하지 않은 재발 가드(konsist)까지 세워 주셨습니다. 다만 그 반영 중 스플래시 처방이 CI 를 red 로 만들었고, 별개로 링크 게이트가 새 정책에 걸립니다. 둘 다 이 PR 안에서 닫혀야 해서 변경을 요청합니다.

이전 지적 대조

# 지적 판정 근거
1 [blocking] 시스템바 아이콘이 안 잠겨 다크 기기에서 흰 아이콘이 사라짐 닫힘 LightEdgeToEdge.kt 신설로 SystemBarStyle.light 를 못박고 MainActivity.kt:26·DebugSettingsActivity.kt:33 이 함께 쓴다. Theme.kt:53-54 에 되돌릴 자리를 병기한 것까지 요청대로입니다
2 [normal] 스플래시가 다크 기기에서 밝은 배경 + 흰 아이콘 닫혔으나 red themes.xml 에 windowLightStatusBar·windowLightNavigationBar. 아래 blocking A
3 [nit] @Config(sdk=[35]) 중복 닫힘 메서드 3곳에서 sdk 제거, qualifiers 만 남김
4 [nit] isSystemInDarkTheme import 가 KDoc 링크 전용 존치 되돌리기용이면 그대로 두시라고 적었던 것이라 그대로가 맞습니다

LightSystemBarLockKonsistTest 는 제가 요청하지 않은 것인데, 무인자 enableEdgeToEdge() 가 새 Activity 를 통해 다시 스며드는 것이 정확히 이 부류가 재발하는 경로입니다. 되돌릴 자리 셋을 KDoc 에 함께 적어 둔 것도 좋습니다.

새 지적

A. [blocking] windowLightNavigationBar 가 minSdk 를 넘겨 :app:lintDebug 가 죽습니다 → themes.xml:20 인라인.

B. [blocking] 대표 Issue 를 Closes 로 걸어야 합니다 — 링크 게이트 red

Repository Quality / Require linked Issue 가 실패합니다.

PR #1723 제목의 대표 Issue #1719를 본문에서도 Closes #1719로 연결하세요.
Refs 로는 대표 Issue를 걸 수 없습니다 — 이 PR이 Issue의 일부만 하면
그 몫을 새 Issue로 분리해 대표 Issue로 삼고 …

이건 작성자 잘못이 아닙니다. 이 규칙은 #1748(ci(platform): PR 대표 Issue 는 Closes 로만 연결한다)이 2026-09-02 21:33 KST 에 들여온 것이고, 이 PR 은 그날 19:31 KST 에 열렸습니다. 제 첫 리뷰(21:49)에서 「Refs #1719 게이트 통과」라고 적은 것도 그 16분 전 기준이라 이미 낡았습니다. 규칙이 PR 밑에서 바뀐 경우입니다.

게이트가 처방까지 적어 줍니다 — 이 PR 몫(라이트 팔레트 잠금 + 시스템바·스플래시 라이트 고정)을 새 Issue 로 떼어 대표 Issue 로 삼고 Closes 로 걸고, #1719 는 Refs 로 덧붙이는 것이 맞습니다. #1719 본체(다크 지원 여부 판정과 토큰 이관)는 이 PR 이 닫지 않으니까요.

확인한 비결함 — 제 첫 리뷰 처방의 안전성

첫 리뷰에서 SystemBarStyle.light(TRANSPARENT, TRANSPARENT) 를 처방하면서 darkScrim 을 투명으로 두라고 했는데, minSdk 26 에서 내비바 보호 scrim 이 사라지는 게 아닌지 소스로 확인했습니다. 문제 없습니다.

activity-1.8.2 의 EdgeToEdge.kt 기준 —

  • light(scrim, darkScrim) 은 detectDarkMode = { false } 라 항상 lightScrim 을 씁니다(:169-175). darkScrim 은 이 경로에서 안 쓰입니다.
  • API 26~28 은 EdgeToEdgeApi26 이 맡고, 거기서 isAppearanceLightNavigationBars = !navigationBarIsDark 를 실제로 설정합니다(:268-272). SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR 가 API 26 부터 있어서 가능합니다.

그래서 코드 경로는 minSdk 26 에서도 온전히 동작합니다. API 27 벽에 걸리는 건 XML 속성 쪽뿐이고, 그게 A 입니다.

검증

  • head f610b086 기준 gh pr checks: fail 2건 — Repository Quality / Repository Quality(Require linked Issue), Static Analysis / Check Project Issues (Android Lint)(:app:lintDebug FAILED). 나머지 전량 pass. 제출 직전 head 재확인했습니다.
  • Lint 는 경고 27건 중 에러 1건이 빌드를 세웠고, 그 1건이 A 입니다. 나머지 27건은 develop 부터 있던 explicit API mode 경고라 이 PR 몫이 아닙니다.
  • mergeable=MERGEABLE, mergeStateStatus=BLOCKED.
  • 시안 대조: 해당 없음(팔레트 선택). 실기동: 미수행 — A 는 Lint 출력, B 는 게이트 로그로 확정했고 둘 다 코드 밖 근거입니다.

Comment thread app/src/main/res/values/themes.xml Outdated
AfternoteTheme 의 isDarkTheme·enableLightEdgeToEdge 와 함께 되돌린다.
-->
<item name="android:windowLightStatusBar">true</item>
<item name="android:windowLightNavigationBar">true</item>

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[blocking] android:windowLightNavigationBar 는 API 27 부터인데 이 저장소 minSdk 는 26 입니다(AndroidCommonConfig.kt:36). :app:lintDebug 가 여기서 죽습니다.

app/src/main/res/values/themes.xml:20: Error: android:windowLightNavigationBar
requires API level 27 (current min is 26) [NewApi]
> Task :app:lintDebug FAILED — Lint found errors in the project; aborting build.

바로 위 windowLightStatusBar 는 API 23+ 라 그대로 두셔도 됩니다. 이 한 줄만 갈리면 됩니다.

처방 둘 중 하나입니다.

  1. values-v27/themes.xml 로 분리 — 이쪽을 권합니다. API 26 에서는 이 속성이 플랫폼에 아예 없어 «되는데 안 걸린» 게 아니라 원래 불가능한 것이고, 리소스 한정자가 그 사실을 코드에 남깁니다.
  2. tools:targetApi="27" 을 항목에 붙이고 tools 네임스페이스를 선언 — 한 줄로 끝나지만 «왜 26 에선 안 되나»가 안 남습니다.

스플래시 구간만의 문제라 영향은 좁습니다. 스플래시가 끝나고 Activity 로 넘어간 뒤에는 enableLightEdgeToEdge() 가 API 26 에서도 내비바 아이콘을 잠급니다 — EdgeToEdgeApi26 이 isAppearanceLightNavigationBars 를 세팅하니까요(SYSTEM_UI_FLAG_LIGHT_NAVIGATION_BAR 가 API 26 부터 있습니다). 그러니 API 26 기기에서 흰 아이콘이 남는 구간은 스플래시뿐이고, 그건 플랫폼 한계지 이 PR 이 더 할 수 있는 게 없습니다.

되돌릴 때 함께 지울 자리라 values-v27 쪽에도 #1719 를 적어 두시면 좋겠습니다.

@github-actions github-actions Bot added the awaiting-author 변경요청 뒤 작성자 조치 없음 — 공은 작성자에게 있다 label Sep 3, 2026
konsist 의 KoFileDeclaration.name 은 확장자를 뺀 이름이라 "LightEdgeToEdge.kt" 와
같아지지 않는다. 제외가 늘 비어 가드가 헬퍼까지 훑고 있었다 — 헬퍼는 인자 있는
호출이라 결과는 같았지만, 죽은 조건으로 남으면 다음 사람이 잘못 믿는다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@github-actions github-actions Bot removed the awaiting-author 변경요청 뒤 작성자 조치 없음 — 공은 작성자에게 있다 label Sep 3, 2026
@github-actions
github-actions Bot requested a review from 1hyok September 3, 2026 11:42

@1hyok 1hyok left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

재판정 — 새 커밋 db5d2fde(fix(konsist): 헬퍼 제외를 파일명이 아니라 경로로 판정한다)를 확인했습니다. konsist 가드를 파일명 대신 경로로 판정하도록 조인 것은 그 자체로 옳습니다 — 같은 이름의 파일이 다른 모듈에 생겨도 면제가 새지 않습니다.

다만 제 직전 리뷰의 blocking 2건과는 무관한 별건이라 변경요청을 유지합니다. 둘 다 그대로입니다.

지적 현재 상태
A. windowLightNavigationBar 가 minSdk 26 을 넘겨 :app:lintDebug 가 죽는다 values-v27/themes.xml 없음. app/src/main/res/values/themes.xml:20 에 그대로
B. 대표 Issue 를 Closes 로 걸어야 한다 본문에 Closes 0건. Repository Quality 가 8초 만에 계속 fail

A 는 values-v27/ 로 그 한 줄만 옮기면 끝나고(위의 windowLightStatusBar 는 API 23+ 라 제자리에 둬도 됩니다), B 는 이 PR 몫을 새 Issue 로 떼어 Closes 로 거는 것이 게이트가 안내하는 처방입니다.

작업 중이신 것 같아 재촉으로 읽히지 않았으면 합니다 — 리뷰 적체 판정이 「저자가 커밋을 올렸다」만 보고 공을 저에게 넘겨서, 상태를 갱신해 두는 쪽이 서로 편할 것 같아 남깁니다.

@github-actions github-actions Bot added the awaiting-author 변경요청 뒤 작성자 조치 없음 — 공은 작성자에게 있다 label Sep 3, 2026
@Sadturtleman Sadturtleman changed the title fix(core-ui): 다크 팔레트 확정 전까지 라이트로 잠근다 (#1719) fix(core-ui,app): 다크 팔레트 확정까지 팔레트·시스템바를 라이트로 잠근다 (#1873) Sep 3, 2026
@github-actions
github-actions Bot requested a review from 1hyok September 3, 2026 22:53
@github-actions github-actions Bot removed the awaiting-author 변경요청 뒤 작성자 조치 없음 — 공은 작성자에게 있다 label Sep 3, 2026
android:windowLightNavigationBar 는 API 27 부터다. minSdk 26 인 기본 values/ 에 두면
:app:lintDebug 가 NewApi 로 죽는다. windowLightStatusBar(API 23+)는 제자리에 둔다.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

@1hyok 1hyok left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

재리뷰 — blocking 2건이 다 닫혔습니다. 승인합니다. 남은 red 는 코드 문제가 아니라 제 쪽에서 풀 일입니다.

이전 지적 대조

지적 판정 근거
A. [blocking] windowLightNavigationBar 가 minSdk 26 을 넘겨 :app:lintDebug 가 죽는다 닫힘 values-v27/themes.xml 을 새로 만들어 그 한 줄을 옮기셨습니다. 제가 「위의 windowLightStatusBar 는 API 23+ 라 제자리에 둬도 된다」고 적은 것까지 그대로 지켜 values/ 쪽엔 남겼고, 옮긴 자리에 「API 27 부터다. minSdk 26 이라 기본 values/ 에 두면 :app:lintDebug 가 NewApi 로 죽는다」를 적어 다음 사람이 되돌리지 않게 했습니다. values/themes.xml 에도 「values-v27/ 에 둔다」는 한 줄을 남겨 두 파일이 서로를 가리킵니다
B. [blocking] 대표 Issue 를 Closes 로 닫힘 #1873 을 Closes 로 걸었습니다

두 파일이 한 쌍이라는 걸 양쪽에 적어 둔 게 이 수정의 값어치입니다. 다크 팔레트를 되살릴 때 되돌릴 자리가 AfternoteTheme · enableLightEdgeToEdge · values/themes.xml · values-v27/themes.xml 넷으로 늘었는데, 새로 만든 파일의 주석이 그 넷을 다 부르고 있어 한 곳만 되돌리는 사고가 안 납니다.

남은 red 는 제가 막고 있는 것입니다

Repository Quality 가 fail 인데, 원인이 코드가 아닙니다.

PR #1723 작성자 @Sadturtleman는 대표 Issue #1873의 담당자(@1hyok)가 아닙니다.

B 를 닫으니 그 다음 가드가 걸린 것입니다. #1873 의 주 담당 모듈이 core 이고, reconcile-issue-metadata.mjs:49 가 core → 1hyok 로 못 박아 두었습니다. 손으로 담당자를 넘겨도 그 조정기가 되돌립니다. 즉 이 red 는 작성자 쪽에서 풀 수 있는 것이 아닙니다.

실제로 이 PR 이 만지는 곳은 app · core/ui · konsist 라 모듈 판정 자체는 맞습니다. 어긋난 건 지도상 core 담당이 저인데 이 작업을 그쪽에서 하셨다는 사실 쪽입니다.

푸는 길은 셋이고, 전부 제가 하거나 제가 결정할 일입니다.

  1. issue-assignee-exempt 라벨 — 게이트 메시지가 안내하는 우회입니다. 붙인 뒤 재검증(본문 수정 또는 push)이 필요합니다.
  2. #1873 담당을 넘기고 모듈 지도도 함께 고치기 — 지도를 안 고치면 조정기가 되돌립니다.
  3. 제가 이 PR 을 가져가기 — 이미 다 하신 작업이라 낭비입니다.

이 red 때문에 다시 커밋을 올리실 필요는 없습니다. 제가 정하고 처리한 뒤 여기 남기겠습니다.

검증

  • 판정은 head f331cbf20 을 직접 읽어 확인했고, 제출 직전에 다시 읽어 같은 값임을 확인했습니다.
  • CI 실패 원인은 run 33815356140 의 실패 로그를 직접 열어 특정했습니다. 같은 로그의 진단이 「GitHub API core 한도는 충분합니다 (남은 4962/5000) — 앞 스텝의 실패는 가드가 실제로 판정한 결과입니다」 를 찍어 유령 실패가 아님을 명시합니다.
  • 담당자 지도는 reconcile-issue-metadata.mjs 의 표를 직접 읽었습니다.
  • 시안 대조: 미확인입니다. Figma 커넥터가 이 세션에서 인증되지 않았습니다. 다만 이 PR 은 「다크 팔레트가 확정될 때까지 라이트로 잠근다」라 시안 값을 따라가는 변경이 아니고, 되살릴 자리를 남기는 것이 본체입니다.

@1hyok 1hyok added the issue-assignee-exempt 담당자 대조 가드 우회 — 대표 Issue 담당자가 아니어도 이 PR 은 통과한다 label Sep 4, 2026
@1hyok

1hyok commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator

담당자 게이트 처리했습니다 — issue-assignee-exempt 라벨을 이 PR 에 붙였습니다.

validate-pr-issue-link.mjs:88 이 라벨을 PR 에서 읽으므로(이슈가 아닙니다) 자리는 맞습니다. Issue 연결 요건 자체는 그대로 살아 있고, 면제되는 건 담당자 대조 하나뿐입니다.

다만 재검증은 다음 push 를 기다려야 합니다. 게이트 메시지가 안내한 workflow_dispatch 로 재검증을 쏴 봤는데 실패했습니다 — run 33829112053, head f331cbf2(이 PR head 와 일치), 잡이 하나도 생성되지 않은 채 워크플로 레벨에서 failure 입니다. #1850 이 실측한 「pr-validation.yml 의 workflow_dispatch 브리지 성공 0건」에 한 건이 더 붙은 셈입니다.

그러니 이 PR 에 아무 push 나 한 번 올라가면 Repository Quality 가 라벨을 읽고 통과합니다. 굳이 이것 때문에 커밋을 만드실 필요는 없고, 충돌 해소나 다른 수정이 생길 때 자연스럽게 풀립니다. 지금 상태에서 코드 쪽으로 고칠 것은 없습니다 — 승인은 그대로입니다.

@Sadturtleman

Copy link
Copy Markdown
Collaborator Author

@1hyok 이 PR 은 승인까지 받았지만 Repository Quality 의 담당자 게이트에서 막혀 있습니다. 제가 우회하지 않고 넘깁니다.

무슨 일이 있었는지 적어 둡니다.

  • 대표 이슈 fix(core-ui,app): 다크 팔레트 확정까지 팔레트·시스템바를 라이트로 잠근다 (#1719 분리) #1873 의 담당자가 @1hyok 이고, 게이트는 PR 작성자가 대표 이슈의 담당자일 것을 요구합니다. 저는 아닙니다.
  • 제가 공동 담당자로 저를 넣어 봤으나 Issue Metadata Guard 가 8초 만에 되돌렸습니다. reconcile-issue-metadata.mjs:49 의 core: "1hyok" 매핑대로이고, 이 수선이 core:ui 와 app 을 건드리니 규칙이 맞습니다. 두 번 시도해 두 번 다 되돌아갔고, 더 밀지 않았습니다.

풀 방법은 둘입니다.

  1. 같은 브랜치로 @1hyok 이 PR 을 다시 여는 것. 게이트가 작성자를 보므로 이쪽이 규칙에 맞습니다.
  2. issue-assignee-exempt 라벨. 다만 그 탈출구는 「담당자 이관을 기다릴 수 없는 긴급 수선」용이고 이 건은 긴급이 아니라, 제가 임의로 붙이지 않았습니다.

어느 쪽이든 판단은 모듈 소유자 몫이라 여기서 멈춥니다. 내용 자체는 리뷰가 끝났고 나머지 검사도 통과 중입니다.

@Sadturtleman
Sadturtleman requested a review from 1hyok September 4, 2026 05:17
@Sadturtleman

Copy link
Copy Markdown
Collaborator Author

@1hyok 라벨 붙여 주셔서 감사합니다. workflow_dispatch 브리지가 잡을 하나도 안 만든 것까지 확인해 주신 덕에 무엇을 기다려야 하는지 분명했습니다.

말씀대로 push 를 만들기 위한 빈 커밋 대신, 밀려 있던 develop 을 들였습니다 — 158 커밋 뒤처져 있었습니다. 충돌은 없었고 :core:ui:compileDebugKotlin · :app:compileDebugKotlin · :konsist:test 통과했습니다. 이걸로 Repository Quality 가 라벨을 읽을 것입니다.

코드 쪽은 그대로입니다.

@github-actions github-actions Bot added the android-test PR head에서 Android Managed Device 계측 테스트 실행 label Sep 4, 2026
@Sadturtleman

Copy link
Copy Markdown
Collaborator Author

@1hyok Pixel 2 API 30 androidTest red 를 고쳤습니다. 코드가 아니라 제 CI Test Plan 이 틀렸습니다.

  • AccessibilitySmokeAndroidTest 는 @SdkSuppress(minSdkVersion = 34) 입니다. 그런데 제가 그 selector 를 device: "api30" 으로 적어 뒀습니다.
  • api30 lane 은 러너 필터에서 그 클래스를 통째로 걸러 내므로 결과 XML 이 한 줄도 안 남습니다. Gradle 은 exit 0, 그 뒤 verify-android-test-plan-result.mjs 가 「Managed Device XML에서 실행 결과를 찾지 못했습니다」로 red 를 냈습니다. 나머지 두 canary 는 정상 기록됐습니다.
  • 그 한 항목만 device: "api34" 로 옮겼습니다. android-managed-device.yml:212 의 api34 lane 은 scheduled_only: false 라 PR 에서 돕니다 — 지금까진 selected 목록에 api34 가 없어 run_lane=false 로 9초 만에 끝나고 있었습니다.

코드는 그대로입니다.

@1hyok 1hyok left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

재요청은 develop 병합 커밋(2ebb5736f) 때문이고 저자 변경은 없습니다. 승인을 유지합니다.

git merge-tree --write-tree <p1> <p2> 가 만든 자동 병합 트리와 이 커밋의 트리가 같은 해시(9703fa1c…) 입니다 — 충돌 해소로 손댄 hunk 가 0 이라는 뜻이라, 병합에 딸려 온 740 파일은 전부 develop 쪽 내용 그대로입니다.

issue-assignee-exempt 라벨이 이번 push 에서 읽혀 Repository Quality 가 pass(9s) 로 바뀌었습니다. 지난 코멘트에서 「다음 push 때 풀린다」고 한 그 자리입니다. 남은 pending 은 GMD·CodeQL 계열이라 기다리면 됩니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

android-test PR head에서 Android Managed Device 계측 테스트 실행 issue-assignee-exempt 담당자 대조 가드 우회 — 대표 Issue 담당자가 아니어도 이 PR 은 통과한다

Projects

None yet

Development

Successfully merging this pull request may close these issues.

fix(core-ui,app): 다크 팔레트 확정까지 팔레트·시스템바를 라이트로 잠근다 (#1719 분리)

2 participants