예제 검증 방법과 확인 경계
자동 테스트, 외부 서비스 live test, Android 실기기 확인은 서로 다른 증거입니다. 하나의 성공을 다른 단계의 성공으로 기록하지 않습니다. 실행 시각, 대상 version, 명령, 종료 코드, artifact SHA-256을 함께 남기면 나중에 같은 결과를 재현할 수 있습니다.
1. 패키지 무결성
현재 저장소의 예제 artifact는 다음과 같습니다.
python tools/morit_plugin.py verify `
examples/plugins/school-life/dist/school-life-1.5.0.mplg
python tools/morit_plugin.py verify `
examples/plugins/notion/dist/notion-1.1.0.mplg
Get-FileHash -Algorithm SHA256 @(
'examples/plugins/school-life/dist/school-life-1.5.0.mplg',
'examples/plugins/notion/dist/notion-1.1.0.mplg'
)
verify는 ZIP 안전성, canonical payload, embedded Ed25519 public key와 signature를 검사합니다.
검증 결과에 publisher key가 포함되어 있어야 하며, trusted publisher 사전 등록 여부와 무관하게
서명 자체가 유효해야 합니다. Host의 신뢰 정책은 설치·실행 단계에서 별도로 적용됩니다.
문서의 hash는 source나 build 규칙이 바뀌면 달라집니다. 새 artifact를 만들었으면 위 명령으로 실제 파일을 다시 계산한 뒤 문서와 배포 metadata를 함께 갱신합니다.
2. 자동 회귀 테스트
저장소 root에서 다음 검사를 먼저 실행합니다.
npx -y @morit/cli plugin validate .\examples\plugins\school-life
npx -y @morit/cli plugin validate .\examples\plugins\notion
python -m unittest discover -s backend/archive_processing -p "test_*.py"
python -m unittest discover -s backend/plugin_mcp -p "test_*.py"
dart analyze
flutter test
관련 backend 테스트는 정상 package 설치·복원·삭제, actor 격리, permission/readiness gate, Connection OAuth state와 replay 차단, credential 암호화·갱신·해제, host-action outbox, Slash·Search·Tool routing, UI/Response 계약을 검사합니다. transport fixture 테스트는 외부 서비스가 응답하지 않아도 request/response parser 계약을 확인하지만 실제 사용자 계정의 성공을 증명하지는 않습니다.
3. Backend live E2E
tools/plugin_live_e2e.py는 임시 Supabase 사용자를 만들고 공개 API를 호출합니다. 관리자 key를
사용하므로 승인된 운영자 환경에서만 실행하며 Secret, OAuth code, access token을 로그에 남기지
않습니다.
$env:MORIT_E2E_ENV = 'C:\secure\morit-backend.env'
$env:MORIT_E2E_API = 'https://morit-api.moring.co'
$env:MORIT_SCHOOL_PLUGIN = 'examples/plugins/school-life/dist/school-life-1.5.0.mplg'
$env:MORIT_NOTION_PLUGIN = 'examples/plugins/notion/dist/notion-1.1.0.mplg'
# 실제 Notion 승인을 할 때만 0보다 큰 값을 사용합니다.
$env:MORIT_E2E_WAIT_NOTION_OAUTH_SECONDS = '300'
$env:MORIT_E2E_NOTION_QUERY = 'Morit 프로젝트'
$env:MORIT_E2E_NOTION_PAGE_QUERY = 'Morit 프로젝트 안내'
$env:MORIT_E2E_NOTION_DATA_SOURCE_QUERY = 'Morit 작업 목록'
python tools/plugin_live_e2e.py
live E2E에서 확인할 핵심 순서는 다음과 같습니다.
- 신규 사용자의 설치·Instance 목록이 비어 있고 traversal package가 부분 상태 없이 차단됨
- 학교와 Notion package를 함께 설치하면 각 설치의 기본 Instance가 정확히 하나 생성됨
- 권한 승인 전 capability가 노출되지 않고, 승인 후 학교 Tool·Search·Slash·background가 등록됨
- 실제 NEIS 조회, 검색, 알림 outbox lease/ACK, 재시작 후 registry 복원이 동작함
- Notion 승인 시 기본 Instance의 Connection이 활성화되고 실제 page/data source를 읽음
- Connection 삭제 후 credential을 다시 쓰지 않으며 capability가 즉시 제거됨
- disable/delete/purge 뒤 cache, 설정, credential, pending action이 남지 않음
같은 외부 서비스를 여러 계정으로 쓰는 경우 설치나 root Instance를 복제하지 않습니다. 하나의
기본 Instance 아래 여러 Connection을 만들고 allow_multiple 정책과 계정별 격리를 검사합니다.
스크립트 결과는 다음처럼 해석합니다.
Notion 사용자 승인을 생략했거나 운영 process 재시작 명령을 주지 않은 실행은 partial입니다.
state=completed나 검색 결과 수만으로 page/data source 본문 조회 성공을 추정하지 않습니다.
4. Android 실기기 확인
Backend live test는 앱 화면과 Android 알림을 누르지 않습니다. release APK를 실제 기기에 설치해 다음을 별도로 확인합니다.
.mplg파일 선택 후 설치·권한·초기 설정 흐름- 학교 후보 선택, 오늘·주간·급식 화면과 빈 상태·오류 상태
- Notion 공식 승인, Connection 추가·전환·해제와 실제 page/data source 표시
- AI 자연어·Slash·Search와 해당 AI 메시지 안의 Response UI
- 알림 권한 승인 후 실제 알림 표시
- 강제 종료·재실행 뒤 설치·연결·화면 상태 복원
- 비활성화·삭제 뒤 화면·capability·알림 제거
Response UI는 정상 데이터에서 필요한 컴포넌트 하나만 선택되는지뿐 아니라 빈 데이터, 관련 없는
질문, 같은 결과의 중복, schema 불일치, 권한 미승인, Tool 실패에서 컴포넌트가 생성되지 않고 일반
텍스트 답변이 유지되는지도 확인합니다. Plugin Response는 plugin.<extension-id> 등록 ID와 실제
실행 capability의 data source가 일치해야 합니다.
실기기에서 확인하지 않은 항목은 자동 테스트가 통과했더라도 미검증으로 남깁니다.
5. 결과 기록 형식
시각(KST):
source revision:
Plugin/Host version:
실행 명령과 종료 코드:
artifact 경로·크기·SHA-256:
자동 테스트:
live E2E:
Android/iOS/Desktop 실기기:
생략 또는 실패한 단계와 이유:
성공 기록에는 실행하지 않은 항목을 넣지 않습니다. iOS·Desktop은 현재 Host 지원 범위를 먼저 확인하고, 지원이 확정되지 않은 플랫폼을 Android 결과로 대신하지 않습니다.