d3ro-voice/docs/map/00-index.md
Yun Chan 99f06c253c fix(llm): stop leaking instruction prompts instead of processed text
Running a custom instruction (translate, summarise, rewrite, explain code,
free prompt) inserted the instruction's own wording instead of the result.
Two faults stacked:

The instruction was passed as the text to process, leaving the system-prompt
argument empty. `BASE_SYSTEM_PROMPTS` has no `custom` key, so resolution fell
back to `refine` without saying so, and the model dutifully polished the
instruction it had been handed. The transcript never reached it.

And only `{{text}}` was substituted, which none of the five built-in
instructions use — they carry `{{targetLanguage}}`, `{{userPrompt}}`, or no
placeholder at all. The substitution was a no-op from the day it was written:
the presets landed ten hours before the code that expected them.

- Instruction prompts now go to the system-prompt argument and the transcript
  to the text argument. Instructions that spell out `{{text}}` keep their old
  meaning, so hand-written ones still work.
- `renderInstructionPrompt` resolves `{{text}}`, `{{userPrompt}}` and
  `{{targetLanguage}}` in one place, and warns by name when a placeholder is
  left standing rather than letting it reach the model.
- `resolveSystemPrompt` no longer drops silently to `refine` for `custom`.
- Voice shortcuts no longer die at the `defaultLLMAction === 'none'` gate; an
  explicitly named instruction outranks the default. Without one, `none` still
  passes the transcript through untouched.
- `translate` receives its target language instead of relying on a default two
  call frames away. It is still always English — `AppConfig` has no key for it,
  and neither `language` (UI locale) nor `sttLanguage` (source language) can
  stand in. Choosing a target language needs a setting and is not in this fix.
- Chains ran instructions with placeholders intact; they share the same
  resolution now.
- The command screen's pipeline bench called `llm.generate`, which preload does
  not expose, so every run threw and the catch showed the input back as if it
  had succeeded. It uses `llm.process` now, over the same path production
  takes, and a failure reads as a failure.

Present since the feature shipped: the custom-instruction path has never
worked. Plain actions (refine, summarise, grammar, expand) were unaffected and
are now covered by tests so they stay that way.
2026-09-21 14:39:26 +09:00

78 lines
5.8 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# D3RO Voice — Feature & Infrastructure Map (Index)
> Status: ACTIVE
> Last full audit: 2026-09-13
> Last update: 2026-09-21 — 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; `11` §7 holds accepted design constraints (things deliberately kept, not gaps)
> Scope: entire monorepo `D:/workspace/D3ROVoice` at product version `1.4.0` (`release/product-version.json`, released 2026-09-21)
> 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.