Some checks failed
ci / 워크스페이스 빌드 검증 (push) Blocked by required conditions
ci / 모바일 린트·타입·Jest (push) Waiting to run
ci / Supabase Edge Functions + Cloudflare Worker (push) Waiting to run
ci / .NET API 서버 테스트 (push) Waiting to run
ci / 정본·보안·린트·타입·테스트 (push) Has been cancelled
deploy-site / deploy (push) Has been cancelled
84 lines
11 KiB
Markdown
84 lines
11 KiB
Markdown
# D3RO Voice — Feature & Infrastructure Map (Index)
|
||
|
||
> Status: ACTIVE
|
||
> Last full audit: 2026-09-13
|
||
> Last update: 2026-09-27 — **v1.7.0·v1.8.0 릴리스 + 기기 간 동기화 재작성 + 운영 DB 정렬.** 데스크톱↔모바일·웹 동기화를 outbox·서버시각 커서·삭제 기록(`sync_tombstones`)·실시간(`ws`) 엔진으로 다시 만들고, 이력·사전·회의·메모 태그·명령·템플릿·지식베이스·녹음·공통 설정·기기 등록까지 넓혔다(MEM-13, ACC-08/09, MEM-05). 운영 Supabase가 `0028`에 멈춰 있던 것을 발견해 `0029`–`0035`를 적용하고 함수 23개를 재배포했다(GAP-OPS-01 — 사용자가 자기 tier를 올릴 수 있던 권한 구멍 포함). 모바일 기기 목록·데이터 내보내기 결함도 고쳤다(GAP-SYNC-03/04). 무서명 로컬 게시 예외(GAP-REL-06) 유지.
|
||
>
|
||
> Previous update: 2026-09-24 — **v1.6.0 릴리스.** 버전 SSOT를 1.6.0(android/iOS 1060000)으로 올렸다. 다음 문장 제안을 1개씩 순차 생성해 최대 12개·3개씩 페이지로 보여 주고(Ctrl+Alt+↑↓ 이동, ←→ 페이지, Enter 수락, Esc 닫기; 기존 기본 단축키는 revision 5에서 이관), 오버레이를 재설계했다(`INPUT-06`/`INPUT-07`). 개인 문구 코퍼스는 터미널·에디터·코딩 에이전트와 비문장·플레이스홀더를 학습하지 않고 기존 데이터도 같은 규칙으로 정리한다(`INPUT-04`/`INPUT-05`). 제안 단축키가 받아쓰기를 켜던 버그, 구버전 사이드카가 `/uia/focus` 없이 남던 버그(런타임 최소 버전 1.5.0), Ollama 러너 콘솔 창, 사이드카 이중 기동을 고쳤다. 실시간 자막 창은 끌어서 옮길 수 있고 첫 자막 전까지 준비 안내를 보인다. 무서명 로컬 게시 예외(GAP-REL-06)를 유지한다.
|
||
>
|
||
> Previous update: 2026-09-22 — **Gemma/Ollama 폭주 방어 계약을 기록했다.** 19:14:12 부팅 워밍업이 `keep_alive: 30m`으로 `gemma4:e4b`를 19:44:12까지 VRAM 3,226,342,521 bytes / context 4096으로 강제 상주시킨 것이 관측됐으며, 같은 시점 Windows GPU Engine PID 표본에는 Ollama의 활성 compute가 없었다. 즉 당시 상태는 무한 추론이 아니라 강제 residency였다. 19:11:17~19:11:58의 자동 제안 연속 생성은 기존 900 ms·12/min·5 candidates·128 tokens·한 글자 재생성 정책이 허용한 burst였다. 현재 구현 계약은 부팅 warmup 제거, `keep_alive: 2m`, 제안 600 ms / 최소 5 s 간격 / 기본 6회·hard max 12회 per min / 3 candidates / 64 tokens / 12-char growth / 8 s timeout, 그리고 요청별 취소·상한·종료 정리다. 독립 표적 검증은 6 test files / 69 tests passed / 0 failed, 변경 코드·테스트 ESLint와 `git diff --check`도 exit 0이다. Raw Ollama에서는 cold bounded 요청이 client hard timeout 15.044 s에 취소된 뒤 `/api/ps`가 비었고 `/api/version`은 80 ms에 회복했다. 명시 warmup은 HTTP 200 / 16.639 s, 후속 warm 요청은 body `options.num_predict=1`, `keep_alive='2m'`로 553 ms HTTP 200 / `done:true` / `eval_count:1` / `done_reason:length`였고 `/api/ps` expiry는 약 119.9 s였다. **19:48:59 +09:00에는 새 generate/unload/kill/retry 없이 충분히 지난 뒤 한 번의 `/api/ps`가 HTTP 200 / 45.8 ms / `{models:[]}`였고 `/api/version`은 HTTP 200 / 7.3 ms / `0.32.13`이었다.** 이는 raw API 수준의 expiry 뒤 unload 확인일 뿐 앱 재시작·GUI·실제 타이핑 증거는 아니므로 상태는 `[~]`로 유지한다 (`11` GAP-LLM-04, GAP-INPUT-06).
|
||
>
|
||
> Previous update: 2026-09-21 — **Input intelligence (입력 레메트리 + 다음 문장 제안) 신규**. 데스크톱에 입력 수집기(`InputTelemetryService`), UIA 컨텍스트 브리지(사이드카 `GET /uia/focus`), 제안 서비스(`SuggestionService`), 어렛 커 오버레이, 설정 > 입력 탭(동의·정책·주간 인사이트·개인 문구)을 추가했다. 카탈로그에 `INPUT-01`~`INPUT-08`(전부 데스크톱 `[~]` — 유닛 48건은 GREEN 이지만 **실앱 타이핑 검증 전**), 백로그에 GAP-INPUT-01~05 + GAP-LLM-03, §7 에 CONSTRAINT-INPUT-01(키 내용 미저장 — ActivityWatch 정책 채택)을 기록. 설계 근거는 조사 기반이다: 어렛은 `GetGUIThreadInfo` 가 아니라 UIA `TextPattern.GetSelection`(Chromium 은 `TextPattern2` 미구현), 타이핑 스트는 키코드 복원이 아니라 UIA 스냅샷 diff(한/일 IME 대응), 디바운스/토큰 한도는 인라인 컴플리션 실측값(Continue 350 / Tabby 250 / twinny 300 ms, 출력 64~256 토큰). 의존성: `koffi` 3.3.1(포그라운드 창 FFI), 사이드카 `uiautomation` 2.0.29 + `comtypes`. 데스크톱 유닛 총계 1409(+49), Electron ABI 실행에서 신규 실패 0건. 당시의 24.7초/4.9초 지연 설명과 `keep_alive: 30m`·부팅 워밍업 처방은 **현재 상태가 아닌 과거 가설/완화 이력**이며, 최신 운영 결론은 위 2026-09-22 항목과 `11` GAP-LLM-04를 따른다. 직전: LLM instruction-prompt fix (`9c2b4d4`): the custom-instruction path inserted the instruction's own wording instead of the processed result and had **never worked in any shipped release** (`v0.1.0-alpha`..`v1.4.0`, introduced `fea923d` 2026-04-05, not a regression). `llm-prompts.ts` is now the SSOT for prompt resolution and placeholder substitution, shared by `VoiceModeService` / `ChainService` / `LLM.PROCESS`. AI-04/05/06/07 are demoted to `[~]` on desktop — fixed with unit tests, but **not verified in a running app** and the four related `tests/red/*.usecase.test.ts` could not execute (`better-sqlite3` ABI). New: GAP-LLM-01 (no target-language setting), GAP-LLM-02 (this fix unverified); GAP-INFRA-06 amended (the ABI masks verification, not just dev-env switching cost); GAP-I18N-01 amended (`popup.error.default` missing in 10 locales). Earlier the same day: CAP-16 (desktop key bindings rebuilt on one `@d3ro/core/keybinding` SSOT — multiple bindings per action, mouse buttons, `HOTKEY` → `KEYBINDING` IPC group), verified on Windows by a manual run, so CAP-16 and CAP-02 are `[x]` and GAP-KEY-01 is closed. Still open: GAP-KEY-02/03, GAP-QA-02, GAP-I18N-01/02, GAP-INFRA-06, GAP-LLM-01/02, GAP-INPUT-01~05; `11` §7 holds accepted design constraints (things deliberately kept, not gaps)
|
||
> Scope: entire monorepo `D:/workspace/D3ROVoice` at product version `1.8.0` (`release/product-version.json`, released 2026-09-27)
|
||
> Purpose: let any agent (or human) answer two questions in under a minute:
|
||
> 1. **What infrastructure exists?** (build, CI, services, APIs, data, packages, deploy)
|
||
> 2. **How far is each feature developed?** (per surface, with file anchors and status)
|
||
|
||
This is the entry point. Read the index, then open only the sub-document you need. Do not read all files every time.
|
||
|
||
---
|
||
|
||
## 1. How to use this map
|
||
|
||
| You need to know… | Open |
|
||
|---|---|
|
||
| The product, its IA, platforms, identity/data model | [`01-system-overview.md`](./01-system-overview.md) |
|
||
| Repo layout, build, CI/CD, Docker, deploy, scripts, docs | [`02-infrastructure.md`](./02-infrastructure.md) |
|
||
| Shared packages (`@d3ro/core`, `ui`, `ui-native`, `i18n`, `api-client`) | [`03-shared-packages.md`](./03-shared-packages.md) |
|
||
| Desktop (Electron) services, IPC, pages, popups, status | [`04-desktop-app.md`](./04-desktop-app.md) |
|
||
| Web (Next.js) routes, components, clients, status | [`05-web-app.md`](./05-web-app.md) |
|
||
| Mobile (React Native) screens, features, tabs, status | [`06-mobile-app.md`](./06-mobile-app.md) |
|
||
| .NET cloud API: controllers, services, tables, auth | [`07-api-server.md`](./07-api-server.md) |
|
||
| Admin back office (Next.js) routes, guards, status | [`08-admin-console.md`](./08-admin-console.md) |
|
||
| Supabase migrations, Edge Functions, Cloudflare worker | [`09-supabase-backend.md`](./09-supabase-backend.md) |
|
||
| **The feature map** — every feature, per platform, with status | [`10-feature-catalog.md`](./10-feature-catalog.md) |
|
||
| **Known gaps / under-developed / backlog** | [`11-gap-backlog.md`](./11-gap-backlog.md) |
|
||
| **Mandatory rules for keeping this map current** | [`12-update-protocol.md`](./12-update-protocol.md) |
|
||
|
||
An agent starting a task should:
|
||
1. Read the relevant surface doc (04–09) for infrastructure.
|
||
2. Read `10-feature-catalog.md` for the feature's current status and platform coverage.
|
||
3. Read `11-gap-backlog.md` to see if the feature is already tracked as backlog.
|
||
4. After finishing, follow `12-update-protocol.md` before the work is considered done.
|
||
|
||
---
|
||
|
||
## 2. Status legend
|
||
|
||
Feature rows in `10-feature-catalog.md` use this scale:
|
||
|
||
| Symbol | Meaning |
|
||
|---|---|
|
||
| `[x]` | Implemented and verified on this platform (code + tests / evidence exist in-repo). |
|
||
| `[~]` | Implemented but partial, unverified, or blocked on an external/console gate. |
|
||
| `[ ]` | Planned or absent on this platform. |
|
||
| `[!]` | Blocked on something outside the repo (external console, secret, physical device, store review). |
|
||
| `[-]` | Not applicable to this platform (with a one-line reason). |
|
||
|
||
Status is **per platform**. A feature can be `[x]` on desktop, `[~]` on mobile, `[ ]` on web.
|
||
|
||
---
|
||
|
||
## 3. One-paragraph system summary
|
||
|
||
D3RO Voice is a multi-platform AI voice assistant (transcription, LLM command execution, meeting intelligence, RAG, voice conversation) sold as Free / Pro / Pro+ / Team / Enterprise tiers. It ships as an **Electron desktop app** (local-first: bundled SoX, faster-whisper sidecar, Ollama, local SQLite), a **React Native mobile app** (`apps/mobile-rn`, cloud-first: Supabase auth + Edge Functions + on-device Whisper fallback), a **Next.js web console**, a **Next.js admin back office**, and a **.NET cloud API** (AI proxy + back office backend). The shared backend is **Supabase** (Postgres + RLS + Auth + Storage + ~27 Deno Edge Functions), deployed to a Synology NAS via Docker with a Cloudflare edge worker and tunnel. Shared code lives in `packages/*`. Distribution: Windows NSIS + macOS DMG (GitLab/Forgejo feed + electron-updater), Android APK/AAB via Google Play.
|
||
|
||
---
|
||
|
||
## 4. Reading order for a brand-new agent
|
||
|
||
1. `AGENTS.md` (root) — operating rules + the obligation to update this map.
|
||
2. `docs/map/01-system-overview.md` — the big picture and IA.
|
||
3. The surface doc for your task (04–09).
|
||
4. `docs/map/10-feature-catalog.md` — find the feature and its status.
|
||
5. `docs/map/11-gap-backlog.md` — check for existing backlog notes.
|
||
|
||
Deeper design history (not required to start): `docs/design/*`, `docs/phases/*`, `docs/v2/*`, `docs/v3/*`, `memory/*`, `CHANGELOG.md`. The mobile SSOT is `docs/v3/MOBILE_APP_COMPLETION_SSOT.md`.
|
||
|
||
---
|
||
|
||
## 5. Maintenance
|
||
|
||
This map must change whenever a feature is added, removed, changed, or deferred.
|
||
See [`12-update-protocol.md`](./12-update-protocol.md) for the exact checklist and
|
||
`AGENTS.md` for the agent obligation.
|