d3ro-voice/AGENTS.md
Yun Chan c3ddd36c6f
Some checks failed
deploy-site / deploy (push) Failing after 40s
docs: record the 1.1.0 release and add the infrastructure map
Release notes for 1.1.0 were split between an Unreleased section and the
version section, so the published notes would have omitted the update-feed
and desktop changes. Everything shipping in this version now sits under one
`## [1.1.0]` heading.

`docs/map/` becomes the entry point for what infrastructure exists per
platform and how far each feature is developed, with a documented update
protocol so feature work and this map do not drift apart again. The release
guide now states that installer binaries live in the update feed rather than
the repository.
2026-09-16 23:27:52 +09:00

8.8 KiB
Raw Permalink Blame History

AGENTS.md — D3RO Voice

Operating guide for any AI agent (or human) working in this repository. Read this first. It tells you where the infrastructure map lives and what you must update when you change the product.


1. What this repo is

D3RO Voice is a multi-platform AI voice assistant monorepo:

  • apps/desktop — Electron desktop app (local-first: SoX + faster-whisper sidecar + Ollama + SQLite)
  • apps/web — Next.js cloud console
  • apps/mobile-rn — React Native product mobile app (cloud-first; active)
  • apps/api-server — ASP.NET Core 10 AI proxy + back office backend
  • apps/admin — Next.js admin back office
  • server/supabase — Postgres + RLS + Auth + Storage + ~27 Deno Edge Functions (canonical product backend)
  • server/cloudflare-worker — edge gateway
  • site/ — landing/marketing/legal site
  • packages/* — shared @d3ro/core, ui, ui-native, i18n, api-client

Full detail: docs/map/01-system-overview.md.


2. The map — read before you work

docs/map/ is the authoritative feature & infrastructure map. Use it to learn what infrastructure exists and how far each feature is developed before writing code.

Start at docs/map/00-index.md. Key files:

Need File
Map index + status legend + how to use docs/map/00-index.md
Product / IA / identity / pipeline docs/map/01-system-overview.md
Repo layout, build, CI/CD, Docker, deploy docs/map/02-infrastructure.md
Shared packages docs/map/03-shared-packages.md
Desktop services/IPC/pages docs/map/04-desktop-app.md
Web routes/components docs/map/05-web-app.md
Mobile screens/features docs/map/06-mobile-app.md
.NET API docs/map/07-api-server.md
Admin console docs/map/08-admin-console.md
Supabase + Cloudflare docs/map/09-supabase-backend.md
Feature map (per platform, with status) docs/map/10-feature-catalog.md
Gaps / backlog / external blockers docs/map/11-gap-backlog.md
How to keep the map current docs/map/12-update-protocol.md

Recommended sequence for a new task:

  1. Read the surface doc for the area you will touch (0409).
  2. Find the feature in 10-feature-catalog.md and check its status per platform.
  3. Check 11-gap-backlog.md so you do not re-plan tracked work.
  4. Do the work.
  5. Update the map before declaring done (see §4).

Mobile status is authoritative in docs/v3/MOBILE_APP_COMPLETION_SSOT.md; the map mirrors and rolls it up. When they disagree, fix the SSOT first, then the map.


3. Non-negotiable repo rules

These come from CLAUDE.md and are enforced here too:

  • TypeScript strict, no any, no console.log (use logger).
  • Services are singletons + EventEmitter. IPC channels are ${feature}:${action} from the SSOT packages/core/src/ipc-channels.ts; wrap errors in D3ROError/ErrorCode and IPCResult.
  • Theme SSOT: only d3roPalette/d3roShadow/d3roTypo/d3roRadius; no hardcoded hex outside theme.ts.
  • i18n: use t(); no hardcoded Korean/English strings in UI.
  • No Co-Authored-By or Claude-related wording in commits. Follow the commit format in the shell tool instructions.
  • Desktop GUI: do not background-launch Electron from an agent subshell (virtual desktop). Tell the user to run run-desktop.bat or an external terminal.
  • Audio device discovery: never execSync (use async exec).
  • GPU: keep app.disableHardwareAcceleration() and --disable-gpu.
  • Desktop: keep app.setName('d3ro-voice') + app.setAppUserModelId at the top; prevent dev silent exit.
  • Never hardcode secrets; production secrets are injected at build/CI time. Fail closed, never fake success.
  • Security-first: only defensive security work.

Build/test commands: docs/map/02-infrastructure.md §3. Root: npm run typecheck, npm run test, npm run lint. Mobile: npm --prefix apps/mobile-rn run lint|typecheck|test.


4. MANDATORY: keep the map updated

Feature change ⇒ map change, in the same commit / PR. A feature is not done until the map reflects it.

Whenever you add, remove, change, or defer a feature, or touch infrastructure, you MUST update the map:

  1. Edit docs/map/10-feature-catalog.md (status per surface + notes/anchors).
  2. Edit the relevant surface doc (0409) if you changed services, routes, screens, IPC channels, tables, Edge Functions, or build/CI.
  3. Edit docs/map/11-gap-backlog.md:
    • resolved gap → [x] + date + evidence;
    • newly deferred item → new row + next step;
    • cleared external blocker → [x] + evidence.
  4. Reconcile with docs/v3/MOBILE_APP_COMPLETION_SSOT.md for mobile changes.
  5. Update docs/map/02-infrastructure.md and the 00-index.md header dates when build/release/CI or the product version changes.

Full procedure and templates: docs/map/12-update-protocol.md.

Status semantics: [x] verified · [~] partial/unverified · [ ] planned/absent · [!] blocked externally · [-] N/A. Never mark [x] on typecheck alone.


5. Definition of done (feature work)

  • Code implemented, wired end-to-end (no TODOs / placeholders / fake success).
  • Tests added/updated and passing; lint/typecheck clean on the touched scope.
  • Relevant surface doc (0409) updated if interfaces changed.
  • 10-feature-catalog.md row updated (status per platform + anchors).
  • 11-gap-backlog.md updated (closed/opened/external).
  • Mobile SSOT reconciled if mobile was touched.
  • No secrets committed; fail-closed preserved.

6. Update & release system

Desktop auto-update runs electron-updater against the canonical Forgejo feed https://git.chanpaca.net/api/packages/yunchan/generic/d3ro-voice/latest. The GitLab project 1172 registry is a legacy mirror for pre-Forgejo installs; runtime must never point at it. Full evaluation and 2026 methodology: docs/deployment/update-system-assessment.md.

These files move together and are enforced by npm run release:metadata:test:

Concern SSOT
runtime feed + channels apps/desktop/src/main/update-feed.ts
builder publish URL apps/desktop/electron-builder.yml
update policy (channels, min version, force, delta/full, rollout, kill switch) release/update-policy.json
policy runtime logic apps/desktop/src/main/update-policy.ts
canonical publisher scripts/ci/publish-forgejo-release.mjs
legacy mirror publisher scripts/ci/publish-gitlab-release.mjs
version SSOT release/product-version.json

Rules:

  • Tag-only, immutable releases. Publish runs only on annotated vX.Y.Z tags. Tags are never moved or deleted; a bad release is fixed forward with a higher patch. Same-version re-release is forbidden by SemVer.
  • Feed contract. UPDATE_FEED_URL == builder publish.url == canonical Forgejo URL. LEGACY_UPDATE_FEED_URL must stay the GitLab mirror.
  • Version discipline. SemVer: feat=MINOR, fix=PATCH, breaking=MAJOR. Run npm run version:sync when syncing surfaces; npm run version:check must be clean.
  • Channels. latest (stable), beta, alpha. Stable clients never receive a prerelease unless their channel allows it.
  • Major vs incremental. release/update-policy.json decides whether an update is mandatory (minimumSupportedVersion, forceInstallBelow) and whether to use a full installer instead of a blockmap delta (fullInstallOnMajorChange, fullInstallVersionGap). stagingPercentage limits rollout; killSwitch stops update checks remotely.
  • Secrets stay fail-closed. Every publisher needs FORGEJO_TOKEN (write:package + write:repository). Desktop releases additionally require the WIN_CSC_* Authenticode material; missing signing data must fail the pipeline.

Commands: npm run release:metadata, npm run release:metadata:test, npm run release:forgejo:check, npm run release:tag -- --dry-run (then npm run release:tag, then git push origin vX.Y.Z). Use --sign when GPG is configured; tags are annotated and immutable. Locally, npm run release:forgejo:local loads FORGEJO_TOKEN from .env (gitignored); CI reads the secret from its store.


7. Where deeper context lives (optional)

  • Design (historical desktop architecture): docs/design/*
  • Build-out phases: docs/phases/*
  • Multi-platform plan: docs/v2/*
  • Mobile SSOT + Play package: docs/v3/*
  • Monetization: docs/monetization-plan.md
  • Deployment/release: docs/deployment/*, release/*, scripts/ci/*
  • Refactor policy + reports: docs/REFACTOR_POLICY.md, docs/REFACTOR_WAVE*_REPORT.md
  • Project log/handoffs: memory/*, CHANGELOG.md

Treat those as history; treat docs/map/* and the code as current.