검색/계층으로 나뉜 데스크톱 앱에 기능을 추가하고 모든 빌드를 테스트한다

계층으로 나뉜 데스크톱 앱에 기능을 추가하고 모든 빌드를 테스트한다

코어, 데스크톱 호스트, 웹 UI로 나뉜 데스크톱 앱을 AI가 고칠 때 쓴다. 규칙은 코어에 두고, 도구가 쓸 수 있는 명령과 폴더를 좁히고, 선택 기능을 실제 의존성에 따라 나누고, 지원하는 모든 빌드를 테스트한 뒤에 완료한다.

이 AI 규칙을 사용하려면
## 코어, 데스크톱 호스트, UI가 각각 무엇을 맡을지 정한다 코드를 변경하기 전에 배포 대상 플랫폼, 지원 클라이언트, 프로세스 토폴로지, 신뢰 경계를 정의한다. - 비즈니스 규칙, 영속성, 실행, 도메인 동작은 기준이 되는 코어에 둔다. - 데스크톱 호스트는 수명 주기, 네이티브 기능, 안전한 연결, 패키징을 담당하게 한다. - 웹 기반 UI는 표현, 탐색, 오케스트레이션을 담당하게 하며 렌더러에 코어 규칙을 중복 구현하지 않는다. - UI에서 코어로 보내는 호출은 임시방편의 직접 접근이 아니라 하나의 인증된 전송 추상화를 통해 전달한다. - 실험용 클라이언트는 전송, 암호화, 릴리스 상태가 명시된 별도의 호환성 표면으로 취급한다. - 각 계층, 계층이 소유한 상태, 공개 인터페이스, 금지된 책임을 명시하는 아키텍처 지도를 유지한다. ## 명령을 위험도로 나누고 도구가 사용자 폴더 안에서만 작업하게 한다 구성을 중앙화하고 작업을 수행하는 모든 도구에 실패 시 차단하는 단일 정책을 적용한다. - 환경 값은 형식이 지정된 구성 모듈을 통해 읽는다. 기능 코드는 프로세스 환경 변수나 빌드 시점 환경 변수에 직접 접근해서는 안 된다. - 자율성은 작업 공간 제한, 신뢰할 수 있는 루트 경로, 설치 권한과 결합된 명시적 단계로 모델링한다. - 명령을 읽기, 쓰기, 네트워크, 설치, 파괴적 작업으로 분류하고 인식되지 않은 명령은 쓰기 작업으로 취급한다. - 활성 단계에 따라 각 분류를 허용, 확인 요청, 차단 중 하나로 결정한다. 시스템 위치와 자격 증명 위치는 항상 차단한다. - 사용자의 작업 루트와 애플리케이션 내부 상태를 분리한다. 도구는 작업 루트 안에서만 동작할 수 있으며 내부 상태에 직접 써서는 절대 안 된다. - 대화형 변경의 승인 관문은 기본적으로 활성화하고, 응답이 없는 요청은 만료시키며, 만료 시 해당 작업을 거부한다. - 애플리케이션 수준의 경로 검증과 운영 체제 또는 컨테이너 샌드박스를 함께 적용한다. 샌드박스는 심층 방어 수단이지 정책 검사를 대체하지 않는다. ## 코어 안을 도메인별 모듈로 나눈다 각 도메인에 책임이 명확하고 작고 조합 가능한 파일로 이루어진 전용 모듈을 부여한다. ### 표준 모듈 구조를 사용한다 - 모듈 파사드는 내보내기에만 집중하고 비즈니스 로직을 포함하지 않는다. - 해당 책임이 존재한다면 직렬화 가능한 도메인 형식, 영속성, 작업, 컨트롤러 스키마, 에이전트 도구, 이벤트 구독자, 테스트를 각각 별도의 파일에 둔다. - 도메인 소유 도구는 해당 도메인에 배치하고, 공유 도구 인프라는 실제로 여러 영역에 걸치는 동작에만 사용한다. - 전송 모듈은 인증, 디스패치, 로깅, 관측 가능성, 프로토콜 관련 사항으로 제한한다. 스키마와 처리기 쌍을 등록부에 두고 컨트롤러를 노출한다. 새로운 동작을 추가할 때는 전송 코드 곳곳에 명령 이름별 분기를 늘리지 말고, 도메인 컨트롤러를 추가하여 단일 조합 지점에서 등록한다. ## 실행 중 켜고 끄기와 컴파일 시점 기능을 따로 다룬다 서로 독립적인 두 축을 모델링한다. - 서비스 집합은 실행할 백그라운드 서비스와 전송 수단을 선택한다. - 도메인 집합은 런타임에 사용할 수 있는 도메인 계열을 선택한다. - 컴파일 시점 기능은 제품 변형에서 코드와 의존성을 제거한다. 런타임 필터링은 비활성화된 도메인의 컨트롤러, 도구, 저장소, 구독자를 실제 제공 표면에서 제거해야 한다. 컴파일 시점 관문은 기본 빌드를 변경하지 않으면서 이 동작과 결합되어야 한다. 등록 지점을 기준으로 삼아 스키마, 디스패치, 도구, 시작 서비스가 서로 어긋나지 않게 한다. ## 실제 의존성을 보고 선택 기능을 끄는 방법을 고른다 항상 활성 상태인 동작을 유지하는 가장 작은 관문을 선택한다. 1. 모든 외부 참조가 등록 지점이라면 말단 관문을 사용한다. 비활성화된 기능의 표면은 실패하는 스텁으로 등록하지 말고 아예 존재하지 않게 한다. 2. 항상 컴파일되는 호출자가 호출 가능한 심벌을 요구할 때만 동작 스텁이 있는 파사드를 사용한다. 3. 의존성이 없는 공유 형식은 항상 컴파일되는 모듈로 분리하고 동작만 스텁으로 대체한다. 활성 빌드와 비활성 빌드 사이에 형식 정의를 절대 중복하지 않는다. 4. 일부 유틸리티가 항상 활성인 도메인에 쓰인다면 디렉터리를 분할한다. 폴더 이름이 아니라 실제 의존성 간선을 차단한다. 5. 선택적 도메인 아래에 있더라도 필수적인 보조 기능은 유지한다. 필요한 구현을 성공한 것처럼 보이는 스텁으로 대체하지 않는다. 기능이 컴파일에서 제외되었는데도 명령이 계속 표시된다면, 오해를 부르는 알 수 없는 명령 오류 대신 비활성 빌드임을 명시하는 오류를 반환한다. 여전히 비활성화된 구성 요소를 지칭하지만 컴파일에는 영향을 주지 않는 데이터는 누락된 식별자를 허용하도록 해석하고 그 계약을 테스트한다. 기능 관문이 의존성을 제거했다는 주장을 컴파일 성공만으로 절대 하지 않는다. 비활성 구성에서 의존성 트리를 역방향으로 조회하여 제거했다고 주장하는 각 의존성이 실제로 사라졌음을 입증한다. ## 선택 기능을 켠 빌드와 끈 빌드를 모두 테스트한다 테스트를 아키텍처의 일부로 취급하고 동작, 통합, 패키징을 모두 다룬다. - 집중된 단위 테스트는 관련 코드와 가까이 배치하고 구현 세부 사항보다 관찰 가능한 동작을 우선한다. - 결정적인 통합 테스트에는 공유 모의 서비스를 사용하며, 단위 테스트 모음에서는 실제 네트워크 접근과 시간에 의존하는 대기를 금지한다. - 성공 경로, 실패, 권한 부여 관문, 복구를 포함한 종단 간 시나리오를 구현 전에 정의한다. - 선택 기능을 양방향으로 테스트한다. 활성화된 경우 등록되었음을 입증하고 비활성화된 경우 존재하지 않음을 입증한다. - 비활성 빌드의 테스트 모음을 명시적으로 실행한다. 컴파일만 하는 스모크 단계는 테스트 코드를 컴파일하지 않으므로 관문이 적용된 테스트가 계속 유효함을 입증할 수 없다. - 변경된 줄에 대한 테스트 커버리지 임계값을 강제하고, 공유 구성이나 기반 계약이 변경되면 전체 테스트 모음으로 전환한다. - 빌드 시스템이 허용한다면 비용이 큰 플랫폼 산출물은 한 번만 빌드하고 그 산출물에서 테스트를 분산 실행한다. ## 비밀 정보와 개인 데이터를 남기지 않는 진단 로그를 추가한다 새롭거나 변경된 흐름에는 진입, 종료, 분기, 외부 호출, 재시도, 시간 초과, 상태 전이, 오류 지점의 진단 정보가 필요하다. - 안정적이고 검색하기 쉬운 도메인 접두사와 요청 ID, 메서드 이름 같은 상관관계 필드를 사용한다. - 일반 로그는 간결하게 유지하되 디버그 및 추적 수준은 표적 조사에 충분한 정보를 제공해야 한다. - 분석 시스템에 비밀 정보, 가공되지 않은 자격 증명, 전체 개인 데이터, 사용자가 작성한 콘텐츠, 엔터티 식별자, 파일 이름, 가공되지 않은 오류 메시지를 절대 기록하지 않는다. - 사용자의 동의를 고려하는 하나의 기능 API를 통해 분석 데이터를 전달하고 콘텐츠를 포함하지 않는 안정적인 이벤트 이름을 사용한다. - 변경 사항이 새로운 실행 경로를 도입했는데 진단 정보가 없다면 구현이 불완전한 것으로 취급한다. ## UI 문구를 모두 번역하고 자동 생성 문서는 손으로 고치지 않는다 지역적인 지름길 대신 중앙화된 상태, 전송, 현지화를 사용한다. - 브라우저 저장소에 상태를 흩어 놓기보다 지정된 애플리케이션 상태 계층을 사용한다. - 모든 코어 호출에는 공유 코어 클라이언트를 사용하고 병렬 전송 수단의 동작을 일치시킨다. - 네이티브 환경 전용 API는 지원되는 런타임 감지기와 오류 경계를 통해 보호한다. - 표시되는 모든 문자열을 현지화 체계에 연결하고, 지원되는 모든 로캘에 실제 번역을 추가하며, 보간 자리표시자를 정확히 보존한다. - 완료 전에 현지화 구문, 남아 있는 영어, 적용 범위를 검사한다. - 생성된 문서 블록을 절대 직접 편집하지 않는다. 소스 마커를 갱신하고 다시 생성한 뒤, 오래된 출력은 드리프트 검사에서 실패하게 한다. - 내장된 타사 뷰에 스크립트 삽입을 추가하지 않는다. 새 동작은 네이티브 처리기, 프로토콜 도구 또는 통제된 IPC 후크를 통해 구현한다. ## 기능을 코어부터 UI까지 차례로 만들고 계층마다 테스트한 뒤 넘어간다 고정된 수직 작업 흐름을 따른다. 1. 기존 도메인 계약, 명명 규칙, 보안 정책, 종단 간 시나리오를 바탕으로 동작을 명세한다. 2. 기준 도메인 로직을 단위 테스트와 함께 구현한다. 3. 통합 테스트로 컨트롤러 또는 RPC 경계를 입증한다. 4. 규칙은 코어에 유지하면서 공유 클라이언트를 통해 해당 동작을 UI에 제공한다. 5. UI 단위 테스트와 플랫폼 종단 간 테스트 범위를 추가한다. 6. 기능을 추가, 제거, 개명할 때 사용자에게 표시되는 기능 메타데이터와 아키텍처 문서를 갱신한다. 현재 계층을 테스트하지 않은 상태에서 다음 계층으로 넘어가지 않는다. 모듈은 작고 단일 목적을 갖게 하며, 문서가 규정하는 동작과 함께 문서도 갱신한다. ## 필수 검사를 건너뛰지 않고 결과를 확인한 뒤 완료라고 말한다 전용 브랜치에서 변경하고 저장소에서 지정한 통합 브랜치를 대상으로 삼으며, 운영 릴리스가 선언된 릴리스 소스와 연결되게 유지한다. - 저장소 루트에서 정식 패키지 관리자, 버전이 고정된 도구 체인, 포매터, 린터, 형식 검사기, 테스트 실행기를 사용한다. - 별도로 빌드되는 네이티브 구성 요소 사이에서 동등한 빌드 프로필 설정을 동기화한다. - 실패를 숨기려고 필수 후크나 검사를 절대 우회하지 않는다. 후크가 파일을 생성하면 결과를 검토하여 포함한 다음 후크를 다시 실행한다. - 변경으로 인해 발생한 실패는 수정하고, 관련 없는 기존 차단 요소는 보호 장치를 조용히 약화하지 말고 문서화한다. - 구현, 테스트, 스키마, 생성 산출물, 현지화, 문서가 일관되는지 최종 차이를 검토한다. - 변경된 모든 계층과 지원되는 모든 빌드 구성에 관련된 검사 결과를 직접 확인하기 전에는 완료를 선언하지 않는다.