Files
hyungi_document_server/contract
hyungi 5383a93f98 feat(ai-fabric): S2 LLM 패브릭 4 provider 결선 + 컴포지션 루트
risk-first 채움(RemoteDS→LocalMLX→OnDevice→Specialized) + makeDefaultRouter 컴포지션 루트.
동결 인터페이스(AIProvider/AIRouter/MockAIProvider) 무변경. SPM AIFabric 단독 빌드·테스트(46 PASS).

- RemoteDS: DSAskClient seam + AskResponse(ask.json) 매핑 + backend exhaustive switch(qwen/cloud TODO)
- LocalMLX: GET /v1/models probe + OpenAI /v1/chat/completions system/user call-shape + non-200 backendError
- OnDevice: FoundationModels 라이브(M5 Max) availability + respond() + GenerationError 9-case 매핑 + stateless/prewarm
- Specialized: scaffold-only(명시 unavailable, vision 폴백 가시화), cloud='claude-cloud' 503
- config 단일소스(env override) + 타임아웃/취소(URLSession 자동 honor, OnDevice 협조적)

실측 동결(S2-3a, M5 Max): availability=available · 취소=COOPERATIVE(~33ms) · 오버플로=exceededContextWindowSize
  · GenerationError 9-case(refusal·concurrentRequests 추가 발견, plan 정정).
한계: LocalMLX fixture=PROVISIONAL_SYNTHETIC(맥미니 offline → 라이브 재캡처 S2-Ff 대기).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-04 17:20:10 +09:00
..

DS App Contract (S1 인터페이스 동결) — v0.1

S1·S2·S3 동시 출발선. 앱(S3)은 실 백엔드/실 LLM 없이 이 디렉토리만 보고 빌드한다.

contract/
  CONTRACT.md            ← 엔드포인트 + 요청/응답 shape 동결 스펙 (읽기 시작점)
  fixtures/              ← 응답 JSON 박제 (앱 프리뷰/디코딩 테스트가 로드)
    auth_login.json            POST /auth/login
    auth_me.json               GET  /auth/me
    documents_list.json        GET  /documents/         (DocumentListResponse)
    document_detail.json       GET  /documents/{id}     (md_status=completed — MD-first 렌더)
    document_detail_pending_md.json  GET /documents/{id} (md_status=pending — extracted_text 폴백 케이스)
    document_content.json      GET  /documents/{id}/content
    documents_tree.json        GET  /documents/tree
    documents_stats.json       GET  /documents/stats/category-counts
    documents_duplicates.json  GET  /documents/duplicates   [S1-ADD] 중복검사
    search.json                GET  /search/
    ask.json                   GET  /search/ask
    memos_list.json            GET  /memos/
    memo_detail.json           GET  /memos/{id}
    digest.json                GET  /digest

동결 원칙

  • 모든 shape는 실제 GPU 백엔드 Pydantic 모델에서 추출(지어내지 않음). [S1-ADD] 필드만 신규.
  • 앱 모델(Swift Codable)은 위 fixtures를 그대로 디코딩할 수 있어야 한다 = 1차 수용 테스트.
  • 통합 시 fixture ↔ 실 응답 call-shape regression으로 대조.

[S1-ADD] (S1이 추가할 신규 — 앱은 옵셔널 디코딩)

  • original_filename, duplicate_of, duplicate_count (DocumentResponse/Detail)
  • GET /documents/duplicates (중복검사 개선 트랙)
  • Word/Excel/이미지/오디오 → md_content 채우기 (MD-first 전포맷 — marker는 현재 PDF 전용)

다음

  • S3: 이 fixtures를 디코딩하는 Swift Codable 모델 + API client(프로토콜) → macOS 앱.
  • S1: [S1-ADD] 구현 + 위 shape 유지(깨면 version bump).
  • S2: /search/ask?backend= + 온디바이스 provider 추상화(AIProvider).