# DeepInterview 静态证据审计报告

- 审计日期：2026-09-07（Asia/Shanghai）
- 目标仓库：`https://github.com/ngoanpv/DeepInterview.git`
- 本地仓库：`/Users/ericyim/ericdoes/ai-interview-research/repos/DeepInterview`
- 审计基线：`241799b39e781737ccec30157d8201bcc572064c`
- 证据口径：以该 HEAD 的可见源码、配置、迁移、测试和 CI 为准；没有真实 API key、没有真实简历、没有付费 API 调用、没有启动长期服务。

## 1. 执行摘要

DeepInterview 是一个 Apache-2.0 的 voice-first AI 模拟面试单体仓库，主要由 Next.js Web、Python/FastAPI Agent、LiveKit 实时语音 worker、LightRAG sidecar、Supabase 持久化和共享类型包组成。源码中确实存在 prep/live/post 三段流水线、LangGraph prep 编排、LiveKit Agent/角色 handoff、CV/JD 解析、公司检索、RAG、评分与报告、内存/Supabase 双持久化、可选认证和本地模型配置；它不是只有 README 或 UI mock。

但成熟度必须分层理解：prep/post 的 mock/offline 路径和大量纯逻辑测试是明确设计目标；实时语音、真实供应商、Supabase/R2、LightRAG 完整后端及本地大模型端到端均依赖外部系统或可选重依赖，本次按授权没有运行。Web 报告页在若干非 ready 状态使用 sample scorecard 作为渲染占位，因此“页面能显示报告”不等于真实访谈已完成评分（`apps/web/app/report/[id]/page.tsx:71-78,98-150`）。

最高优先风险是默认信任边界：当 `INTERNAL_API_SECRET` 为空时 Agent 写端点不鉴权；读端点依赖不可猜 session id 的 capability 模型。源码自己也明确将其描述为 trust-the-network，适合本地但不适合直接暴露公网（`apps/agent/src/deepinterview_agent/api/auth.py:1-11,25-37`）。其次是隐私与治理：会持久化 CV URL/JD、上下文、逐字稿和评分，但仓库中没有看到自动保留期、用户删除/导出或字段级加密机制；本地 tracing 默认开启，虽然 prompt 预览默认关闭（`.env.example:132-150`）。

本次没有安装依赖。安全执行了三项不联网/不需要密钥的验证：Python 源码编译检查、安装脚本 Bash 语法检查、Docker Compose 配置解析，全部通过。没有声称 pytest/Vitest/构建通过；它们因依赖未安装而记为“未运行”。

## 2. 结论标签

- **已实现**：可见执行源码或数据结构直接支持。
- **mock/占位**：显式 mock、sample、fallback 或仅视觉 affordance。
- **README 宣称**：文档声称已验证，但本次没有独立运行对应集成。
- **未验证**：源码存在，但依赖密钥、网络、模型、容器构建或外部服务，本次未执行。

## 3. 版本基线

| 项目 | 结果 | 证据/方法 |
|---|---|---|
| 远端 URL | `https://github.com/ngoanpv/DeepInterview.git` | `git remote get-url origin` |
| 默认分支 | `main` | `refs/remotes/origin/HEAD -> origin/main` |
| HEAD | `241799b39e781737ccec30157d8201bcc572064c` | `git rev-parse HEAD` |
| Commit 日期 | `2026-09-03T15:38:16+07:00` | `git log -1 --format=%cI` |
| Commit 标题 | `feat(tracing): local JSONL tracing with CLI and API viewers` | `git log -1` |
| 项目版本 | `0.3.0` | `package.json:2-7`; `apps/agent/pyproject.toml:1-6` |
| License | Apache License 2.0 | `LICENSE:2-6`; `package.json:5-7` |
| 工作树 | 干净，`main...origin/main` | 报告前 `git status --short --branch` |
| 仓库大小 | 工作树约 6.0 MiB；`.git` 约 3.3 MiB；HEAD tar.gz 约 3.6 MiB | `du -sh`；注意 `.git` 为 blob-filter partial clone，且含首次超时留下的约 2.73 MiB 临时 pack garbage，不代表远端完整历史体积 |
| 文件数 | 372 个文件 | HEAD 源码归档 `find -type f` |

克隆说明：首次普通 clone 在网络传输时超时并由 Git 自动清理；第二次使用 `--filter=blob:none` 成功取得 refs/HEAD，但 checkout 取 blob 超时。随后从 GitHub codeload 下载**同一 HEAD** 的 tar.gz，填充工作树并执行 `git reset --mixed HEAD`；最终工作树与 HEAD 比对干净，未改动源码内容，默认分支保持 `main`。

## 4. 模块与目录架构

### 4.1 顶层边界

- **已实现 — `apps/web/`**：Next.js 16 + React 19 前端，负责 setup、LiveKit 房间 UI、报告、Supabase auth、R2 上传和对 Agent API 的服务端代理。关键依赖见 `apps/web/package.json:13-32`。
- **已实现 — `apps/agent/`**：FastAPI、LangGraph、prep/live/post、provider adapters、worker、评分、coach 和持久化。核心依赖见 `apps/agent/pyproject.toml:7-18`；重型 LiveKit 和 observability 为 extras（同文件 `:20-52`）。
- **已实现 — `services/lightrag/`**：独立 FastAPI knowledge sidecar；默认 NaiveRAG 只有 FastAPI/Uvicorn/Pydantic，真实 LightRAG/RAG-Anything/sentence-transformers 为可选 extra（`services/lightrag/pyproject.toml:7-21`）。
- **已实现 — `packages/shared/`**：TS 共享契约；README 声称是跨语言 source of truth 并镜像为 Pydantic（`README.md:187`），CI 会重新生成 schema 并用 `git diff --exit-code` 检查漂移（`.github/workflows/ci.yml:54-58`）。
- **已实现 — `supabase/migrations/`**：profiles、sessions、RLS、billing 历史迁移、prep progress、coach transcript、profile hardening。
- **已实现 — `cli/`、`skills/`**：初始化/trace/skill pack 工具及版本化面试 playbook；question planner 会检索 pack 并限制注入字符预算（`apps/agent/src/deepinterview_agent/prep/nodes.py:215-269`）。
- **部署 — `docker-compose.yml`**：base stack 为 web + agent-api + lightrag；voice worker 在 `live` profile；Ollama/Whisper/Kokoro 在 `local` profile（`docker-compose.yml:3-10,78-124,125-173,175-216`）。

### 4.2 依赖注入和适配器

`Deps` 将 Settings、LLM、Search、Embeddings、Knowledge 和 Repository 组合成一个依赖包，provider 切换集中在配置与工厂，不进入业务节点（`apps/agent/src/deepinterview_agent/core/deps.py:21-44`）。默认 bundle 被缓存，避免每个 API 请求重建 Supabase HTTP client（同文件 `:47-62`）。

LLM 层有 `GeminiLLM`、`OpenAILLM` 和基于 OpenAI-compatible endpoint 的 `OllamaLLM`；缺 key、mock provider 或未知 provider 均退回 `MockLLM`（`apps/agent/src/deepinterview_agent/core/adapters/llm.py:91-273`）。Search 可见 Tavily + Mock；`.env.example` 还列出 Exa，但当前 `get_search` 可见分支只实现 mock/tavily，因此 Exa 应判为**配置/文档占位或未接通**（`apps/agent/src/deepinterview_agent/core/adapters/search.py:21-70`; `.env.example:109-115`）。Knowledge 是 `HttpKnowledge`/`MockKnowledge`（`apps/agent/src/deepinterview_agent/core/adapters/knowledge.py:41-139`）。

## 5. 端到端流程

### 5.1 Prep

1. Web setup 收集 CV/JD/company/language；无对象存储时，客户端会把文件原始字节转为 base64 data URL（`apps/web/components/setup/setup-form.tsx:212-232`）。
2. Agent 创建 session，先提取 CV，再做质量校验。无意义 CV+JD 会直接 `rejected`，不花模型调用；junk company 只产生 warning 并跳过公司研究（`apps/agent/src/deepinterview_agent/prep/__init__.py:100-160`）。
3. LangGraph topology 是三路并发：`fetch_cv -> cv_analysis`、`jd_analysis`、`company_research`，join 后 `gap_matching -> question_planner`（`apps/agent/src/deepinterview_agent/prep/graph.py:1-16,35-59`）。
4. CV/JD/公司/Gap 各节点调用结构化 LLM；失败时降级为 mock/minimal 模型并写 warning（`apps/agent/src/deepinterview_agent/prep/nodes.py:74-212`）。公司研究实际调用 search adapter，保存 title/url/snippet citation（同文件 `:148-196`）。
5. 生成 `InterviewContext`，状态设为 `ready`，然后把 CV/JD/company 材料按 session id best-effort ingest 到 knowledge store（`apps/agent/src/deepinterview_agent/prep/__init__.py:136-166`）。

结论：Prep 核心为**已实现**；真实 LLM/搜索为**未验证**；mock fallback 为**已实现的 mock 路径**。

### 5.2 简历与 JD

- `extract_cv_text` 支持 plain text、base64 `data:`、HTTP(S) URL，使用 MarkItDown 解析 PDF/DOCX/HTML；扫描 PDF 可在配置 Gemini 时 fallback 到多模态提取（`apps/agent/src/deepinterview_agent/prep/cv_extract.py:1-24,46-72`）。
- 文档远程抓取超时设为 5 秒，解析使用临时文件；模块注释明确最坏情况返回空文本+warning 而不是抛错（同文件 `:46-54,87-104`）。
- JD 当前是文本输入，通过结构化 LLM 生成 `JobSpec`，没有看到专门的 JD 文件解析管线（`apps/agent/src/deepinterview_agent/prep/nodes.py:117-131`）。
- 风险：允许服务端解析用户提供的 HTTP(S) URL，必须持续审查 SSRF、重定向、DNS rebinding、响应大小和内容类型。LightRAG sidecar 有 `_is_public_http_url` 检查入口（`services/lightrag/src/lightrag_service/app.py:39-69`），但 CV 抓取路径的同等级网络边界在本次未完整动态验证。

### 5.3 Live

- Web 通过 `livekit-client` 和 `@livekit/components-react` 加入房间、消费转写和展示 transcript（`apps/web/components/interview/live-room.tsx:42-63,275-334`）。typed answers 会单独合并，因为它们绕过 STT（同文件 `:291-334`）。
- Python worker 构造 `AgentSession`，按配置选择 STT/LLM/TTS，捕获 committed conversation items 到 flat transcript，并在结束时持久化 context/transcript、触发评分（`apps/agent/src/deepinterview_agent/worker.py:93-125,218-275,333-475,658-716,748-916`）。
- STT：Deepgram、Soniox、本地 OpenAI-compatible Whisper；LLM：Gemini/OpenAI/本地 OpenAI-compatible；TTS：Cartesia、ElevenLabs、本地 Kokoro，部分语言 fallback 到 Gemini TTS（同文件 `:141-275,333-475`）。这是**worker 层的 provider 工厂实现**，并非与 prep LLM adapter 完全同一抽象。
- Native LiveKit persona handoff 已有 coding/behavioral specialist，并传递运行中的 chat context（`apps/agent/src/deepinterview_agent/live/handoffs.py:1-15`; `apps/agent/src/deepinterview_agent/live/interviewer.py:203-224`）。
- `SessionGuard` 对最长时长与 transcript turn 数设硬上限，触发 spoken wrap-up + draining shutdown（`apps/agent/src/deepinterview_agent/live/guard.py:1-15,56-125`）。`TranscriptFlusher` 周期 checkpoint，降低进程硬崩时的数据损失窗口（`apps/agent/src/deepinterview_agent/live/flusher.py:1-14,35-86`）。
- **未验证**：真实 LiveKit room、音频设备、barge-in、VAD/turn detector、STT 准确率、TTS 音频、provider latency 和跨 persona handoff。源码注明 worker 需要 livekit extra 和真实 key，且 worker 自身为手工 integration-tested、无 offline unit test（`apps/agent/src/deepinterview_agent/worker_coach.py:3-26`）。

### 5.4 Post、评分与报告

- Evaluator 按已回答 question 并发评分（并发上限 4），把 competency 强制绑定到 plan target、分数 clamp 到 0–5、由数值确定 mastery band；同 competency 多题取平均。空 transcript 不打 0，而是跳过并由 coverage 单独表达（`apps/agent/src/deepinterview_agent/post/evaluator.py:33-51,54-80,83-109,112-152`）。
- 可选 adversarial verifier 只复核 weak/developing，失败保持原分数；默认关闭（`apps/agent/src/deepinterview_agent/post/verifier.py:1-14,55-75,77-123`）。
- 报告整体分是 competency 平均值，weak list 由 weak/developing 派生，coverage 为已答/计划题数；LLM 生成 narrative 和每个已答问题的 model answer（`apps/agent/src/deepinterview_agent/post/report.py:48-79,90-145`）。
- `run_score` 有同进程 per-session lock 和已完成 short-circuit，避免常见重复计费；无答案时标记 `no_answers` 且不持久化误导性零分报告（`apps/agent/src/deepinterview_agent/post/__init__.py:180-239`）。每阶段有 timeout/fallback，目标是 degraded report 而不是丢失整场结果（同文件 `:196-203,241-250`）。
- Web 报告渲染 overall、competency chart、strengths/gaps、language report、next steps、model answers；但 sample fallback 广泛存在，必须通过状态区分真实/样例（`apps/web/app/report/[id]/page.tsx:98-150,375-497`）。报告中的“播放”符号当前只是视觉 affordance，没有真实录音（`apps/web/components/report/transcript-section.tsx:11-17`）。

## 6. 数据模型与状态持久化

Pydantic 核心对象包括 `CandidateProfile`、`JobSpec`、`CompanyIntel`、`GapAnalysis`、`PlannedQuestion`/`QuestionPlan`、`AnswerRecord`、`CompetencyScore`、`LanguageReport`、`ScoreCard`、`StudyPlan`、`InterviewContext` 及 API request/response（`apps/agent/src/deepinterview_agent/shared_models.py:39-341`）。`InterviewContext` 是 prep 写、live 追加、post 读取的共享 blackboard；README 对该 spine 的描述与源码一致（`README.md:162-187`）。

`SessionRepository` 定义 create/load/save context、append answer、status、scorecard、interview transcript、coach transcript、progress、warnings 和 view（`apps/agent/src/deepinterview_agent/core/persistence/repository.py:31-55`）。

- **MemoryRepository 已实现**：进程内 singleton，重启丢失；同时更新 canonical context 的 answers（同文件 `:80-170,312-328`）。
- **SupabaseRepository 已实现但未验证**：service-role client 延迟导入，持久化 context/scorecard/transcript；半配置会明确报错并 fallback 到内存（同文件 `:173-252,308-328`）。
- **数据库结构已实现**：`profiles` 绑定 `auth.users`；`sessions` 包含 company/cv_url/jd_text/language/context/scorecard/transcript；profiles/sessions 开 RLS 且 owner-only（`supabase/migrations/0001_init.sql:2-28`）。Coach transcript 后续单列，避免覆盖 interview transcript（`supabase/migrations/0004_coach_transcript.sql:1-5`）。

一致性风险：Supabase `append_answer` 是 read-modify-write，没有数据库原子 append 或乐观版本条件（`apps/agent/src/deepinterview_agent/core/persistence/repository.py:231-241`）；多 worker 并发时可能 lost update。Scoring lock 也只是单进程内字典锁，不提供跨实例互斥（`apps/agent/src/deepinterview_agent/post/__init__.py:180-193`）。

## 7. RAG、公司研究与闭环学习

- 公司研究：Search adapter 的结果进入 LLM synthesis，并把原始结果映射为 citations（`apps/agent/src/deepinterview_agent/prep/nodes.py:166-196`）。当前可确认 Tavily + Mock；Exa 未见工厂实现。
- Knowledge：无 `LIGHTRAG_URL` 时使用 deterministic `MockKnowledge`；配置后使用 HTTP sidecar（`apps/agent/src/deepinterview_agent/core/adapters/knowledge.py:61-139`）。
- Sidecar 默认 `NaiveRAG`：文本切块、简单 token relevance、top-k；真实 `LightRAGBackend` 为另一实现并由 `RAG_BACKEND` 选择（`services/lightrag/src/lightrag_service/backend.py:34-39,66-138,156-211`）。
- Prep 完成后以 session id 分区 ingest CV/JD/company；Coach 使用同一 session id 检索，形成 document-grounded 回路（`apps/agent/src/deepinterview_agent/prep/__init__.py:162-166`; `apps/agent/src/deepinterview_agent/coach/__init__.py:78-98,132+`）。
- 可选 skill distiller 在评分后只写 review queue，不直接污染 live library，且默认关闭（`apps/agent/src/deepinterview_agent/post/__init__.py:160-177`）。

## 8. 认证、安全与隐私

### 已有控制

- Agent write endpoints 可用 `X-Internal-Secret`，采用 `hmac.compare_digest`；配置后缺失/不匹配返回 401（`apps/agent/src/deepinterview_agent/api/auth.py:25-37`）。
- Web 支持 Supabase SSR cookie refresh 和 `auth.getUser()`；未配置 Supabase 时跳过（`apps/web/lib/supabase/server.ts:12-51`; `apps/web/lib/supabase/middleware.ts:13-62`）。
- Supabase sessions 为 owner RLS（`supabase/migrations/0001_init.sql:19-22`），profiles 后续收紧为只读 owner policy 并撤销客户端写权限（`supabase/migrations/0005_profiles_hardening.sql:17-23`）。
- Compose 默认把 agent-api/lightrag/local-model 端口绑定到 loopback；注释要求公网部署设置 secret（`docker-compose.yml:13-19,35-54,125-173`）。
- LightRAG sidecar 有可选 shared secret，并对远程 URL 做 public HTTP URL 检查（`services/lightrag/src/lightrag_service/app.py:39-81`）。
- Trace 默认不存 prompt preview；只有 `TRACE_INCLUDE_PROMPTS=1` 才记录前 500 字（`.env.example:132-150`）。
- CI 包含 Gitleaks（`.github/workflows/ci.yml:14-26`）。

### 风险与缺口

1. **高：默认空 secret 使写端点开放。** 本地合理，公网危险；可能创建 session、触发付费 LLM、覆盖历史。必须在生产 fail closed、网络隔离、轮换 secret，并最好换成服务身份/JWT/mTLS。
2. **高：读接口 capability-only。** 报告页源码明确 OSS 不做 auth gate（`apps/web/app/report/[id]/page.tsx:209-217`）。session id 是 UUID 派生且不可猜降低风险，但 URL 泄露、日志/Referer/分享仍可暴露敏感 CV 与 transcript。
3. **高：敏感数据生命周期不完整。** 数据结构持久化 `cv_url`、`jd_text`、context、transcript、scorecard（`apps/agent/src/deepinterview_agent/core/persistence/repository.py:58-75`; `supabase/migrations/0001_init.sql:9-15`）；未见自动 retention、用户删除/导出、字段级加密或录音同意记录。
4. **中：SSRF/资源消耗面。** CV URL 和 KB file URL 可触发服务端下载；需要统一 DNS/IP 重验、重定向限制、最大 body、MIME allowlist、压缩炸弹/恶意 PDF 防护和 egress policy。
5. **中：fallback 可能掩盖生产故障。** 缺 key 或未知 provider 自动回 mock（`apps/agent/src/deepinterview_agent/core/adapters/llm.py:243-273`）；如果生产误配置，可能产出看似有效的 mock 结果。应按环境区分 dev fallback 与 prod fail-fast，并在 UI/scorecard 写 provenance。
6. **中：跨实例并发与幂等不足。** 内存锁和 read-modify-write 在横向扩展时不安全；应加 DB transaction/version、唯一 idempotency key 和 distributed lock。
7. **中：镜像供应链。** Compose 使用若干 `latest` 镜像（`docker-compose.yml:125-168`）；生产应 pin digest、生成 SBOM、扫描基础镜像。Agent Dockerfile 在 frozen sync 失败时会 fallback 到非 frozen sync（`apps/agent/Dockerfile:41-49,60-75`），削弱可复现性。
8. **低/产品诚实性：样例与真实结果混用。** 状态逻辑会用 sample scorecard 填充多种非 ready UI；应显著标记“示例”，避免用户误认。

## 9. 外部依赖与部署需求

### 基础工具链

- Node >=20、pnpm 11.5.2、TypeScript 5.9、Turborepo、Python >=3.11、uv；README 还要求 Docker（`package.json:7-24`; `README.md:45-63`）。
- Web：Next 16、React 19、LiveKit JS、Supabase JS、AWS S3 client、Recharts、Zod（`apps/web/package.json:13-42`）。
- Agent core：Pydantic、FastAPI、Uvicorn、HTTPX、LangGraph/LangChain、MarkItDown（`apps/agent/pyproject.toml:7-18`）。

### 可选/真实集成

- LLM：Gemini、OpenAI；本地 Ollama/OpenAI-compatible。
- STT：Deepgram、Soniox、本地 Whisper-compatible。
- TTS：Cartesia、ElevenLabs、Gemini fallback、本地 Kokoro-compatible。
- Realtime：LiveKit server/cloud 及 livekit-agents plugins。
- Data/Auth：Supabase Postgres/Auth；CV/录音对象存储为 Cloudflare R2/S3-compatible。
- Search/RAG：Tavily；LightRAG/RAG-Anything/sentence-transformers；默认可使用 Mock/NaiveRAG。
- Observability：本地 JSONL tracing 默认有；Sentry/Langfuse 可选（`apps/agent/pyproject.toml:46-52`; `.env.example:132-150`）。

本地模型 profile 会拉取多 GB 镜像/模型；源码明确 Ollama 默认模型 `qwen3:8b`、context 16384，并为 Whisper/Kokoro 配独立容器（`docker-compose.yml:114-173`）。本次未拉取或启动。

## 10. 测试、CI 与本次验证

### 仓库测试资产

- Agent：25 个 `test_*.py`；pytest 配置在 `apps/agent/pyproject.toml:67-69`。
- LightRAG：1 个 `test_*.py`。
- Web：2 个 Vitest 文件；shared：1 个 Vitest 文件。
- CI 会安装 pnpm/uv 依赖、生成 schema、build、typecheck、lint、运行 `pnpm test`、LightRAG pytest、两种 compose config，并构建 Docker 镜像（`.github/workflows/ci.yml:31-106`）。

### 安装脚本预检

`scripts/setup.sh` 只包含 `pnpm install` 和 Agent `uv sync`，并提示随后 build/init/test（`scripts/setup.sh:4-13`）。这会下载依赖，因此本次没有执行。Dockerfiles 同样会进行 pnpm/uv 安装，worker/RAG/local profiles 会引入较大依赖或模型（`apps/web/Dockerfile:23-29,57-66`; `apps/agent/Dockerfile:31-75`; `services/lightrag/Dockerfile:3-24`）。

### 实际执行结果

| 验证 | 命令 | 结果 | 边界 |
|---|---|---|---|
| Python 语法/字节码编译 | `python3 -m compileall -q apps/agent/src services/lightrag/src`（在同 HEAD 临时源码副本） | **PASS** | 不导入第三方依赖，不代表运行测试通过 |
| Setup Bash 语法 | `bash -n scripts/setup.sh` | **PASS** | 未执行安装命令 |
| Compose 配置解析 | `docker compose -f docker-compose.yml --project-directory <HEAD-source> config -q` | **PASS** | 未 build、pull 或启动服务；只验证 base compose 展开 |
| Git 工作树一致性 | `git status --short --branch` | **PASS**：`## main...origin/main` | 证明报告时源码未改动 |

### 未运行/未验证

- `pnpm test`、Agent pytest、LightRAG pytest、build/typecheck/lint：依赖未安装；没有把“存在测试”误报为“测试通过”。
- Docker image build 与健康检查：会下载依赖/镜像，未执行。
- LiveKit/STT/LLM/TTS 真链路、Supabase/R2、Tavily、LightRAG extra、本地大模型：需要密钥、外部服务或大下载，未执行。
- README 声称“tests green”“2026-07 Docker 29/Compose v5 base services zero-key healthy”（`README.md:37,65-75`）仅记录为**README 宣称**，不是本次验证结果。

## 11. 可复用设计

1. **统一 blackboard + 分阶段算力**：prep/post 用强模型，live 走低延迟模型，`InterviewContext` 串联三段，边界清晰。
2. **配置驱动 provider 工厂**：业务节点只依赖 Protocol/Deps；Mock、云厂商和 OpenAI-compatible 本地服务可替换（`apps/agent/src/deepinterview_agent/core/deps.py:21-44`）。
3. **结构化输出 + deterministic post-processing**：LLM 负责语义判断，但 competency identity、score clamp、band、overall、coverage 等关键不变量由代码固定，降低模型漂移。
4. **失败隔离**：per-question 并发调用单点失败不摧毁整段；stage timeout 后输出 degraded report；无答案不伪造零分完整报告。
5. **实时路径耐久性**：turn 外异步 flusher + shutdown final write-back + transcript recovery，兼顾延迟与 crash loss window。
6. **默认轻量 RAG、重型后端 opt-in**：NaiveRAG 能让 base stack/offline 测试不依赖 ML；LightRAG 作为 extra。
7. **review queue 学习闭环**：从访谈蒸馏 playbook 但不直接写 live library，符合 human-in-the-loop。
8. **跨语言 schema 漂移检查**：共享 TS schema + Pydantic 镜像，CI 强制生成物无 diff。

## 12. 构建同类系统的启示

- 从第一天就把“内容状态”写入结果：`real/mock/degraded/sample/provider/model/version` 应作为正式 provenance，而不是只靠日志和 UI 状态推断。
- 将外部调用分为离线 deterministic contract tests、provider sandbox tests、端到端媒体 tests；为 STT/LLM/TTS 维护录制 fixture 与延迟/质量基线。
- 把生产配置设为 fail closed：auth secret、持久化、provider key、对象存储、trace 隐私、CORS/egress 不能沿用本地 fallback。
- 对 CV/JD/transcript 建立明确的数据分类、同意、retention、删除/导出、审计和区域策略；对 prompt/trace 默认最小化。
- 用事务/版本字段实现 answer append 和 scoring exactly-once；不要依赖进程内锁支撑多实例。
- 将实时媒体 transport、conversation orchestration 和 provider selection 拆成三个独立契约，避免 worker 成为供应商分支集中点。
- 评分体系应继续坚持代码不变量，并补充 rubric calibration、inter-rater agreement、bias/语言公平性和 adversarial evaluation。
- 对 README 的“verified”声明绑定 CI artifact、commit 和测试矩阵，避免时间性陈述与当前 HEAD 脱节。

## 13. 风险优先级汇总

| 优先级 | 缺口 | 建议 |
|---|---|---|
| P0/P1 | 生产默认可空 `INTERNAL_API_SECRET`、read capability-only | 生产启动 fail-fast；服务身份/JWT/mTLS；网关限流；用户级授权 |
| P1 | CV/JD/transcript 生命周期与删除治理缺失 | retention + deletion/export API + consent + encryption/key policy |
| P1 | 真实语音/provider 未在本次验证 | 固定测试账号与 sandbox，录制 fixture，CI/nightly integration matrix |
| P2 | Supabase read-modify-write 与进程内 scoring lock | DB transaction/version、幂等键、distributed coordination |
| P2 | fallback 到 mock 可能掩盖生产误配 | 环境感知 fail-fast；所有输出标注 provenance |
| P2 | URL ingest/文档解析攻击面 | egress allowlist、DNS/IP 重验、大小/MIME/重定向限制、隔离解析 |
| P2 | `latest` 镜像和非 frozen fallback | digest pin、SBOM、签名/扫描、移除 production 非 frozen fallback |
| P3 | sample 与真实报告易混淆 | UI 强标示示例；真实路径禁止 sample 数据进入 analytics/export |

## 14. 查阅文件清单

以下为本次实际用于证据归纳的主要文件（另做了目录和全仓关键词扫描）：

- 根目录：`README.md`, `LICENSE`, `.env.example`, `package.json`, `pnpm-workspace.yaml`, `docker-compose.yml`
- CI/部署：`.github/workflows/ci.yml`, `.github/workflows/deploy.yml`, `apps/agent/Dockerfile`, `apps/web/Dockerfile`, `services/lightrag/Dockerfile`, `scripts/setup.sh`, `docs/LOCAL_MODELS.md`
- Agent 入口/配置：`apps/agent/pyproject.toml`, `apps/agent/src/deepinterview_agent/app.py`, `core/config.py`, `core/deps.py`, `core/tracing.py`
- Provider：`core/adapters/base.py`, `llm.py`, `search.py`, `knowledge.py`, `embeddings.py`, `mock.py`
- Prep：`prep/__init__.py`, `prep/graph.py`, `prep/nodes.py`, `prep/state.py`, `prep/cv_extract.py`, `prep/prompts.py`
- Live：`worker.py`, `worker_coach.py`, `live/state.py`, `live/interviewer.py`, `live/director.py`, `live/handoffs.py`, `live/guard.py`, `live/flusher.py`, `live/coach_agent.py`
- Post/Coach：`post/__init__.py`, `post/evaluator.py`, `post/language_coach.py`, `post/report.py`, `post/verifier.py`, `coach/__init__.py`
- API/存储：`api/auth.py`, `api/prep.py`, `api/score.py`, `api/session.py`, `api/kb.py`, `api/views.py`, `core/persistence/repository.py`, `shared_models.py`
- RAG：`services/lightrag/pyproject.toml`, `services/lightrag/src/lightrag_service/app.py`, `backend.py`
- Web：`apps/web/package.json`, `lib/livekit.ts`, `lib/r2.ts`, `lib/session.ts`, `lib/supabase/server.ts`, `lib/supabase/middleware.ts`, `components/setup/setup-form.tsx`, `components/interview/live-room.tsx`, `components/report/transcript-section.tsx`, `app/report/[id]/page.tsx`
- 数据库：`supabase/migrations/0001_init.sql` 至 `0006_drop_billing.sql`
- 测试资产：`apps/agent/tests/`, `services/lightrag/tests/`, `apps/web/**/*.test.ts(x)`, `packages/shared/**/*.test.ts`

## 15. 审计限制

这是固定 HEAD 的深入静态审计加轻量配置验证，不是渗透测试、供应链漏洞扫描、依赖安装后的完整测试、模型质量评估或真实媒体集成认证。由于用户要求优先完成可复现证据且不安装大型模型/启动服务，本报告对所有需要真实 key、外部系统、镜像构建或大模型下载的能力明确标记“未验证”。
