{"repo": "andyan77/diyu-agent-legacy-20260711t234248z", "files": {".env.example": {"5518b44801ef48f1331f225c02caed4b03bf60c6": {"t": 1785747130.060063, "n": 4044, "h": "aa2f49c92bead050", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\n#\n# ⚠️ URL 编码警告 — 密码若含特殊字符 (/,+,@,:,?,#,[,]) 必须 URL 编码\n# asyncpg 直连路径不会自动解码, 未编码的 `/` 会被当路径分隔符 → ValueError\n# 编码工具: python3 -c \"from urllib.parse import quote; print(quote('<密码>', safe=''))\"\n# 示例: 密码 \"abc/123+x\" → 编码后 \"abc%2F123%2Bx\"\n# 对应错误症状: asyncpg.connect_utils:244 ValueError: invalid literal for int()\n#\n# Application connection (non-superuser, RLS applies)\n# Run `bash infra/seed/setup-app-user.sh` to create diyu_app user\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n# Migration connection (superuser, for alembic only)\nALEMBIC_DATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# Worker connection (BYPASSRLS, for Celery beat system tasks like quota timeout recovery)\n# MUST point to diyu_worker role (BYPASSRLS), NOT diyu_app or diyu superuser.\n# Run `bash infra/seed/setup-worker-user.sh` to create diyu_worker and auto-update .env.\n# Fail-closed: quota_timeout.py raises RuntimeError if this var is missing.\nWORKER_DATABASE_URL=postgresql+asyncpg://diyu_worker:CHANGE_ME@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === Embedding (Memory Core pgvector, ADR-042) ===\n# 过渡配置; ModelRegistry 建成后迁移至 DB(见 05 Section 5.2 / 06 L795)\nEMBEDDING_MODEL=text-embedding-3-small\nEMBEDDING_DIMENSION=1536\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\n# LITELLM_MODEL 国内默认 deepseek/deepseek-chat(OpenAI 兼容 · 可直连)· 海外/CI 可改 gpt-4o\nLITELLM_MODEL=deepseek/deepseek-chat\n# LLM_BACKEND: real (default) | stub (回滚/开发用,返回固定文本)\nLLM_BACKEND=real\n\n# --- Primary provider (国内默认 · DeepSeek · OpenAI 兼容协议) ---\n# DEEPSEEK_API_KEY(DeepSeek API 密钥)· LiteLLM model 名 \"deepseek/deepseek-chat\" / \"deepseek/deepseek-reasoner\"\n# 国内真实 LLM 调用 / ADR-078 Stage 3 实测 / E2E 全部默认走 DeepSeek\nDEEPSEEK_API_KEY=\nDEEPSEEK_BASE_URL=https://api.deepseek.com/v1\n\n# --- Second provider (T2-2 / P4 R-1: Qwen 备) ---\n# DASHSCOPE_API_KEY(阿里云通义千问 · dashscope API 密钥)· LiteLLM model 名 \"dashscope/qwen-max\" / \"dashscope/qwen-turbo\"\n# 首次使用:scripts/mvp/generate-persona-blindtest.py 走一次性调用(K-DATA-01 Persona 盲测)\n# 正式接入 LLMRouter(allowed_models 白名单 / fallback 主→备 / audit)归 T2-2 独立 PR\nDASHSCOPE_API_KEY=\n\n# --- OpenAI 可选(国内不可用 · 海外环境 / CI 可选启用)---\n# OPENAI_API_KEY=\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === CORS (G1-7 · FS-01 v0.2 HIGH-2) ===\n# 前端 store H5 (3003) / hq (3002) / admin (3001) / web (3000) 跨域调后端 API 时启用\n# 安全约束:\n# 1. allow_credentials=True 不允许 \"*\",必须显式列表 (Cookie 模式必备)\n# 2. 非 local/test 环境 (APP_ENV ∉ {local, test}) 必须显式设置且不得含 loopback\n# (localhost / 127.0.0.1 / 0.0.0.0 / ::1) — 启动时 fail-closed (router.py\n# _resolve_cors_origins · 防 `cp .env.example .env` 后忘改的攻击路径)\n# 默认行为:\n# - APP_ENV=local 或 test: 不设此变量 → 代码内置 dev 默认 (localhost 3000-3003)\n# - APP_ENV=production / staging: 必须显式设置为真实域名列表, 例如:\n# CORS_ALLOWED_ORIGINS=https://store.example.com,https://hq.example.com\n# 注意: 本行刻意保持注释状态, 防止 cp 后未改即生效落入 dev origins\n# CORS_ALLOWED_ORIGINS=\n\n# CSP connect-src 扩展(前后端分离部署时配置 backend host · 默认空 = 仅 'self')\n# 示例: CSP_CONNECT_SRC_EXTRA=http://localhost:8000\nCSP_CONNECT_SRC_EXTRA=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "286c355389c337f36ae5e9d6bcaa0bde204d30a7": {"t": 1785770617.0299373, "n": 4044, "h": "aa2f49c92bead050", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\n#\n# ⚠️ URL 编码警告 — 密码若含特殊字符 (/,+,@,:,?,#,[,]) 必须 URL 编码\n# asyncpg 直连路径不会自动解码, 未编码的 `/` 会被当路径分隔符 → ValueError\n# 编码工具: python3 -c \"from urllib.parse import quote; print(quote('<密码>', safe=''))\"\n# 示例: 密码 \"abc/123+x\" → 编码后 \"abc%2F123%2Bx\"\n# 对应错误症状: asyncpg.connect_utils:244 ValueError: invalid literal for int()\n#\n# Application connection (non-superuser, RLS applies)\n# Run `bash infra/seed/setup-app-user.sh` to create diyu_app user\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n# Migration connection (superuser, for alembic only)\nALEMBIC_DATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# Worker connection (BYPASSRLS, for Celery beat system tasks like quota timeout recovery)\n# MUST point to diyu_worker role (BYPASSRLS), NOT diyu_app or diyu superuser.\n# Run `bash infra/seed/setup-worker-user.sh` to create diyu_worker and auto-update .env.\n# Fail-closed: quota_timeout.py raises RuntimeError if this var is missing.\nWORKER_DATABASE_URL=postgresql+asyncpg://diyu_worker:CHANGE_ME@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === Embedding (Memory Core pgvector, ADR-042) ===\n# 过渡配置; ModelRegistry 建成后迁移至 DB(见 05 Section 5.2 / 06 L795)\nEMBEDDING_MODEL=text-embedding-3-small\nEMBEDDING_DIMENSION=1536\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\n# LITELLM_MODEL 国内默认 deepseek/deepseek-chat(OpenAI 兼容 · 可直连)· 海外/CI 可改 gpt-4o\nLITELLM_MODEL=deepseek/deepseek-chat\n# LLM_BACKEND: real (default) | stub (回滚/开发用,返回固定文本)\nLLM_BACKEND=real\n\n# --- Primary provider (国内默认 · DeepSeek · OpenAI 兼容协议) ---\n# DEEPSEEK_API_KEY(DeepSeek API 密钥)· LiteLLM model 名 \"deepseek/deepseek-chat\" / \"deepseek/deepseek-reasoner\"\n# 国内真实 LLM 调用 / ADR-078 Stage 3 实测 / E2E 全部默认走 DeepSeek\nDEEPSEEK_API_KEY=\nDEEPSEEK_BASE_URL=https://api.deepseek.com/v1\n\n# --- Second provider (T2-2 / P4 R-1: Qwen 备) ---\n# DASHSCOPE_API_KEY(阿里云通义千问 · dashscope API 密钥)· LiteLLM model 名 \"dashscope/qwen-max\" / \"dashscope/qwen-turbo\"\n# 首次使用:scripts/mvp/generate-persona-blindtest.py 走一次性调用(K-DATA-01 Persona 盲测)\n# 正式接入 LLMRouter(allowed_models 白名单 / fallback 主→备 / audit)归 T2-2 独立 PR\nDASHSCOPE_API_KEY=\n\n# --- OpenAI 可选(国内不可用 · 海外环境 / CI 可选启用)---\n# OPENAI_API_KEY=\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === CORS (G1-7 · FS-01 v0.2 HIGH-2) ===\n# 前端 store H5 (3003) / hq (3002) / admin (3001) / web (3000) 跨域调后端 API 时启用\n# 安全约束:\n# 1. allow_credentials=True 不允许 \"*\",必须显式列表 (Cookie 模式必备)\n# 2. 非 local/test 环境 (APP_ENV ∉ {local, test}) 必须显式设置且不得含 loopback\n# (localhost / 127.0.0.1 / 0.0.0.0 / ::1) — 启动时 fail-closed (router.py\n# _resolve_cors_origins · 防 `cp .env.example .env` 后忘改的攻击路径)\n# 默认行为:\n# - APP_ENV=local 或 test: 不设此变量 → 代码内置 dev 默认 (localhost 3000-3003)\n# - APP_ENV=production / staging: 必须显式设置为真实域名列表, 例如:\n# CORS_ALLOWED_ORIGINS=https://store.example.com,https://hq.example.com\n# 注意: 本行刻意保持注释状态, 防止 cp 后未改即生效落入 dev origins\n# CORS_ALLOWED_ORIGINS=\n\n# CSP connect-src 扩展(前后端分离部署时配置 backend host · 默认空 = 仅 'self')\n# 示例: CSP_CONNECT_SRC_EXTRA=http://localhost:8000\nCSP_CONNECT_SRC_EXTRA=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "35abb05dd2351148222eb4c2c3f39df8e65ae03a": {"t": 1785770618.6089246, "n": 3233, "h": "d08875f5586cd1df", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\n#\n# ⚠️ URL 编码警告 — 密码若含特殊字符 (/,+,@,:,?,#,[,]) 必须 URL 编码\n# asyncpg 直连路径不会自动解码, 未编码的 `/` 会被当路径分隔符 → ValueError\n# 编码工具: python3 -c \"from urllib.parse import quote; print(quote('<密码>', safe=''))\"\n# 示例: 密码 \"abc/123+x\" → 编码后 \"abc%2F123%2Bx\"\n# 对应错误症状: asyncpg.connect_utils:244 ValueError: invalid literal for int()\n#\n# Application connection (non-superuser, RLS applies)\n# Run `bash infra/seed/setup-app-user.sh` to create diyu_app user\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n# Migration connection (superuser, for alembic only)\nALEMBIC_DATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# Worker connection (BYPASSRLS, for Celery beat system tasks like quota timeout recovery)\n# MUST point to diyu_worker role (BYPASSRLS), NOT diyu_app or diyu superuser.\n# Run `bash infra/seed/setup-worker-user.sh` to create diyu_worker and auto-update .env.\n# Fail-closed: quota_timeout.py raises RuntimeError if this var is missing.\nWORKER_DATABASE_URL=postgresql+asyncpg://diyu_worker:CHANGE_ME@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === Embedding (Memory Core pgvector, ADR-042) ===\n# 过渡配置; ModelRegistry 建成后迁移至 DB(见 05 Section 5.2 / 06 L795)\nEMBEDDING_MODEL=text-embedding-3-small\nEMBEDDING_DIMENSION=1536\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\n# LITELLM_MODEL 国内默认 deepseek/deepseek-chat(OpenAI 兼容 · 可直连)· 海外/CI 可改 gpt-4o\nLITELLM_MODEL=deepseek/deepseek-chat\n# LLM_BACKEND: real (default) | stub (回滚/开发用,返回固定文本)\nLLM_BACKEND=real\n\n# --- Primary provider (国内默认 · DeepSeek · OpenAI 兼容协议) ---\n# DEEPSEEK_API_KEY(DeepSeek API 密钥)· LiteLLM model 名 \"deepseek/deepseek-chat\" / \"deepseek/deepseek-reasoner\"\n# 国内真实 LLM 调用 / ADR-078 Stage 3 实测 / E2E 全部默认走 DeepSeek\nDEEPSEEK_API_KEY=\nDEEPSEEK_BASE_URL=https://api.deepseek.com/v1\n\n# --- Second provider (T2-2 / P4 R-1: Qwen 备) ---\n# DASHSCOPE_API_KEY(阿里云通义千问 · dashscope API 密钥)· LiteLLM model 名 \"dashscope/qwen-max\" / \"dashscope/qwen-turbo\"\n# 首次使用:scripts/mvp/generate-persona-blindtest.py 走一次性调用(K-DATA-01 Persona 盲测)\n# 正式接入 LLMRouter(allowed_models 白名单 / fallback 主→备 / audit)归 T2-2 独立 PR\nDASHSCOPE_API_KEY=\n\n# --- OpenAI 可选(国内不可用 · 海外环境 / CI 可选启用)---\n# OPENAI_API_KEY=\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "293c6c13bf447ce8d8c34b67494b52099e713197": {"t": 1785770619.960083, "n": 2866, "h": "6611525f05b32fa9", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\n#\n# ⚠️ URL 编码警告 — 密码若含特殊字符 (/,+,@,:,?,#,[,]) 必须 URL 编码\n# asyncpg 直连路径不会自动解码, 未编码的 `/` 会被当路径分隔符 → ValueError\n# 编码工具: python3 -c \"from urllib.parse import quote; print(quote('<密码>', safe=''))\"\n# 示例: 密码 \"abc/123+x\" → 编码后 \"abc%2F123%2Bx\"\n# 对应错误症状: asyncpg.connect_utils:244 ValueError: invalid literal for int()\n#\n# Application connection (non-superuser, RLS applies)\n# Run `bash infra/seed/setup-app-user.sh` to create diyu_app user\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n# Migration connection (superuser, for alembic only)\nALEMBIC_DATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# Worker connection (BYPASSRLS, for Celery beat system tasks like quota timeout recovery)\n# MUST point to diyu_worker role (BYPASSRLS), NOT diyu_app or diyu superuser.\n# Run `bash infra/seed/setup-worker-user.sh` to create diyu_worker and auto-update .env.\n# Fail-closed: quota_timeout.py raises RuntimeError if this var is missing.\nWORKER_DATABASE_URL=postgresql+asyncpg://diyu_worker:CHANGE_ME@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === Embedding (Memory Core pgvector, ADR-042) ===\n# 过渡配置; ModelRegistry 建成后迁移至 DB(见 05 Section 5.2 / 06 L795)\nEMBEDDING_MODEL=text-embedding-3-small\nEMBEDDING_DIMENSION=1536\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n# LLM_BACKEND: real (default) | stub (回滚/开发用,返回固定文本)\nLLM_BACKEND=real\n# --- Second provider (T2-2 / P4 R-1: Qwen 主→DeepSeek 备) ---\n# DASHSCOPE_API_KEY(阿里云通义千问 · dashscope API 密钥)· LiteLLM model 名 \"dashscope/qwen-max\" / \"dashscope/qwen-turbo\"\n# 首次使用:scripts/mvp/generate-persona-blindtest.py 走一次性调用(K-DATA-01 Persona 盲测)\n# 正式接入 LLMRouter(allowed_models 白名单 / fallback 主→备 / audit)归 T2-2 独立 PR\nDASHSCOPE_API_KEY=\n# DEEPSEEK_API_KEY=\n# DEEPSEEK_BASE_URL=https://api.deepseek.com/v1\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "67dedc3b5e808a8166520b74bdc1080246cdabe2": {"t": 1785770621.4182024, "n": 2596, "h": "a9f25fd7bada41c8", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\n#\n# ⚠️ URL 编码警告 — 密码若含特殊字符 (/,+,@,:,?,#,[,]) 必须 URL 编码\n# asyncpg 直连路径不会自动解码, 未编码的 `/` 会被当路径分隔符 → ValueError\n# 编码工具: python3 -c \"from urllib.parse import quote; print(quote('<密码>', safe=''))\"\n# 示例: 密码 \"abc/123+x\" → 编码后 \"abc%2F123%2Bx\"\n# 对应错误症状: asyncpg.connect_utils:244 ValueError: invalid literal for int()\n#\n# Application connection (non-superuser, RLS applies)\n# Run `bash infra/seed/setup-app-user.sh` to create diyu_app user\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n# Migration connection (superuser, for alembic only)\nALEMBIC_DATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# Worker connection (BYPASSRLS, for Celery beat system tasks like quota timeout recovery)\n# MUST point to diyu_worker role (BYPASSRLS), NOT diyu_app or diyu superuser.\n# Run `bash infra/seed/setup-worker-user.sh` to create diyu_worker and auto-update .env.\n# Fail-closed: quota_timeout.py raises RuntimeError if this var is missing.\nWORKER_DATABASE_URL=postgresql+asyncpg://diyu_worker:CHANGE_ME@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === Embedding (Memory Core pgvector, ADR-042) ===\n# 过渡配置; ModelRegistry 建成后迁移至 DB(见 05 Section 5.2 / 06 L795)\nEMBEDDING_MODEL=text-embedding-3-small\nEMBEDDING_DIMENSION=1536\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n# LLM_BACKEND: real (default) | stub (回滚/开发用,返回固定文本)\nLLM_BACKEND=real\n# --- Second provider placeholder (T2-2 / P4 R-1: Qwen主→DeepSeek备) ---\n# DEEPSEEK_API_KEY=\n# DEEPSEEK_BASE_URL=https://api.deepseek.com/v1\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "002a83c6d5cf14b8fc8f1273ead923a7a3b15ca0": {"t": 1785770623.2464511, "n": 2286, "h": "4fb91397dd861bae", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\n# Application connection (non-superuser, RLS applies)\n# Run `bash infra/seed/setup-app-user.sh` to create diyu_app user\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n# Migration connection (superuser, for alembic only)\nALEMBIC_DATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# Worker connection (BYPASSRLS, for Celery beat system tasks like quota timeout recovery)\n# MUST point to diyu_worker role (BYPASSRLS), NOT diyu_app or diyu superuser.\n# Run `bash infra/seed/setup-worker-user.sh` to create diyu_worker and auto-update .env.\n# Fail-closed: quota_timeout.py raises RuntimeError if this var is missing.\nWORKER_DATABASE_URL=postgresql+asyncpg://diyu_worker:CHANGE_ME@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === Embedding (Memory Core pgvector, ADR-042) ===\n# 过渡配置; ModelRegistry 建成后迁移至 DB(见 05 Section 5.2 / 06 L795)\nEMBEDDING_MODEL=text-embedding-3-small\nEMBEDDING_DIMENSION=1536\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n# LLM_BACKEND: real (default) | stub (回滚/开发用,返回固定文本)\nLLM_BACKEND=real\n# --- Second provider placeholder (T2-2 / P4 R-1: Qwen主→DeepSeek备) ---\n# DEEPSEEK_API_KEY=\n# DEEPSEEK_BASE_URL=https://api.deepseek.com/v1\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "70bed908e9222094304fa4d7ec50d65a36da3fbc": {"t": 1785770626.5176134, "n": 1869, "h": "3e58cd08a13e04a5", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\n# Application connection (non-superuser, RLS applies)\n# Run `bash infra/seed/setup-app-user.sh` to create diyu_app user\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n# Migration connection (superuser, for alembic only)\nALEMBIC_DATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === Embedding (Memory Core pgvector, ADR-042) ===\n# 过渡配置; ModelRegistry 建成后迁移至 DB(见 05 Section 5.2 / 06 L795)\nEMBEDDING_MODEL=text-embedding-3-small\nEMBEDDING_DIMENSION=1536\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n# LLM_BACKEND: real (default) | stub (回滚/开发用,返回固定文本)\nLLM_BACKEND=real\n# --- Second provider placeholder (T2-2 / P4 R-1: Qwen主→DeepSeek备) ---\n# DEEPSEEK_API_KEY=\n# DEEPSEEK_BASE_URL=https://api.deepseek.com/v1\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "a190866b5b84cc6a9954d7069c15aca26d4c090e": {"t": 1785770627.689189, "n": 1692, "h": "772e8d1170814bb2", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\n# Application connection (non-superuser, RLS applies)\n# Run `bash infra/seed/setup-app-user.sh` to create diyu_app user\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n# Migration connection (superuser, for alembic only)\nALEMBIC_DATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n# LLM_BACKEND: real (default) | stub (回滚/开发用,返回固定文本)\nLLM_BACKEND=real\n# --- Second provider placeholder (T2-2 / P4 R-1: Qwen主→DeepSeek备) ---\n# DEEPSEEK_API_KEY=\n# DEEPSEEK_BASE_URL=https://api.deepseek.com/v1\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "7e5b9624c65789d9923d7333c11df83f49fc9822": {"t": 1785770629.0701861, "n": 1622, "h": "8347e3236542cac7", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\n# Application connection (non-superuser, RLS applies)\n# Run `bash infra/seed/setup-app-user.sh` to create diyu_app user\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n# Migration connection (superuser, for alembic only)\nALEMBIC_DATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n# --- Second provider placeholder (T2-2 / P4 R-1: Qwen主→DeepSeek备) ---\n# DEEPSEEK_API_KEY=\n# DEEPSEEK_BASE_URL=https://api.deepseek.com/v1\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "e804814ec8b0cd6998057dd843a1077ed6a0c4cb": {"t": 1785770630.2628949, "n": 1483, "h": "59cf78e39f364373", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\n# Application connection (non-superuser, RLS applies)\n# Run `bash infra/seed/setup-app-user.sh` to create diyu_app user\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n# Migration connection (superuser, for alembic only)\nALEMBIC_DATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "dc4c40af5be5bde3d281ddbe6a0ae195fe15d6dc": {"t": 1785770635.0930495, "n": 1238, "h": "a6369d3e00dacbe1", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "e60cda87a519f69791e16dd36656d76fcd4367f0": {"t": 1785770636.4136584, "n": 1259, "h": "b9e56785f3b797ec", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\nDATABASE_POOL_SIZE=5\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Without this key, auth middleware is DISABLED in local env (APP_ENV=local).\n# For local dev with auth enabled, generate and set:\n# python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "3a9ebe0b300c873cd530169b39ecf1b4af9f6f0a": {"t": 1785770638.0696115, "n": 1136, "h": "74d572dad0ef4f00", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\nDATABASE_POOL_SIZE=5\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n\n# === Authentication ===\n# JWT signing key — required for Gateway JWT middleware (G1-1).\n# Generate: python -c \"import secrets; print(secrets.token_urlsafe(32))\"\nJWT_SECRET_KEY=\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "1b9904ec2b13c543e0c140d9f5a823f58970b2ce": {"t": 1785770639.4331596, "n": 957, "h": "92e701a04b3d239f", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\n# Host port defaults to 5433 to avoid conflicts with local PostgreSQL installations\nPG_HOST_PORT=5433\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5433/diyu\nDATABASE_POOL_SIZE=5\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "9f0fb8ac30331bc8b70ff1623184d75e554ca224": {"t": 1785770640.7571123, "n": 855, "h": "9f6d15620a637ed3", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5432/diyu\nDATABASE_POOL_SIZE=5\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === MinIO (Object Storage) ===\nMINIO_ENDPOINT=http://localhost:9000\nMINIO_ACCESS_KEY=minioadmin\nMINIO_SECRET_KEY=minioadmin\nMINIO_BUCKET=diyu-uploads\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}, "9f2fe93320b6f7d59d91301da5379870cfaf170a": {"t": 1785770642.0976353, "n": 702, "h": "ec19ccef64bcd157", "c": "# Diyu Agent Environment Configuration\n# Copy to .env and fill in values\n# Ref: D3 §8.4 (S2: no hardcoded config), D4 §3 (tech stack)\n\n# === Application ===\nAPP_ENV=local\nAPP_PORT=8000\nAPP_LOG_LEVEL=INFO\n\n# === Database (PostgreSQL 16 + pgvector) ===\nDATABASE_URL=postgresql+asyncpg://diyu:diyu@localhost:5432/diyu\nDATABASE_POOL_SIZE=5\n\n# === Redis 7+ ===\nREDIS_URL=redis://localhost:6379/0\n\n# === Neo4j 5.x (Knowledge Graph) ===\nNEO4J_URI=bolt://localhost:7687\nNEO4J_USER=neo4j\nNEO4J_PASSWORD=changeme\n\n# === Qdrant (Vector Store) ===\nQDRANT_URL=http://localhost:6333\n\n# === LLM (via LiteLLM) ===\nLITELLM_API_KEY=\nLITELLM_MODEL=gpt-4o\n\n# === Governance ===\nPHASE_LEVEL=P0\nEVIDENCE_DIR=evidence/local/\n"}}, "docs/evidence/adr-078-stage3/README.md": {"5518b44801ef48f1331f225c02caed4b03bf60c6": {"t": 1785747266.7841477, "n": 5666, "h": "1551fb5ef497d2e9", "c": "# ADR-078 Stage 3 · 流式 Port Expand 实测证据(✅ 已通过 · DeepSeek 主路径)\n\n> **Status**: `✅ 已通过 — DeepSeek 5/5 稳定性 PASS · 2026-04-25`\n> **Gate**: [ADR-078 §Stage 3](../../adr/ADR-078-conversation-port-streaming.md#Stage-3) · `stream_options 稳定性实测通过`\n> **FD-03 裁决**: D3 口径解除 · 本 gate 通过 · PR #294 合入前置已满足\n> **Provider 策略**: 国内默认 DeepSeek(OpenAI 兼容协议 · 国内可直连)· OpenAI 可选(海外 / CI 环境)· Anthropic / Qwen 为降级验证\n> **证据**: [`deepseek-stream-usage-5x.txt`](deepseek-stream-usage-5x.txt) · 5/5 runs · 末块 usage=9 / prompt=7 / completion=2 / finish_reason=stop · 全部非 None\n\n---\n\n## §1 证据要求(gate 定义)\n\nADR-078 §Stage 3 对 PR #294 合入的硬约束:\n\n```\nStage 3 | 单原子 PR · Port Expand 全量闭环(决策二 8 项影响点)\n | `make preflight` 全绿 · `stream_options` 稳定性实测通过\n```\n\n**核心 gate**:`stream_options={\"include_usage\": True}` 在真实 OpenAI 系列 provider 下的稳定性实测。\n\n---\n\n## §2 当前证据状态(runtime_verified · 2026-04-25)\n\n### §2.1 已完成部分\n\n- ✅ **allowlist 前置校验**:unit 测试覆盖([test_route_stream_allowlist.py](../../../tests/unit/gateway/test_route_stream_allowlist.py))\n- ✅ **LLMProviderError 异常包装**:unit 测试覆盖([test_route_stream_provider_error.py](../../../tests/unit/gateway/test_route_stream_provider_error.py) `TestRouteStreamProviderError`)\n- ✅ **provider 分流 (supported_openai_params)**:unit 测试覆盖(同上 `TestRouteStreamProviderSplit`)\n- ✅ **末块 usage 合并**:unit 测试覆盖(同上 `test_openai_usage_only_tail_chunk_merged_*`)\n- ✅ **LLM_CALL audit 四态**:FD-03 F-HIGH-03 Phase C 新增(`TestRouteStreamAuditEvents`)\n- ✅ **mypy strict**:`src/gateway/llm/router.py` → Success no issues\n- ✅ **preflight-fast**:3262 passed · 2 pre-existing fail (alembic env · 非本 PR)\n\n### §2.2 **待补证部分**(Stage 3 核心 gate)\n\n| 项 | 状态 | 证据 / 原因 |\n|---|---|---|\n| 真实 **DeepSeek** provider `stream_options.include_usage=True` 稳定性(国内默认) | ✅ **通过** | 2026-04-25 · 5/5 runs · 末块 usage=9 / prompt=7 / completion=2 / finish_reason=stop · [deepseek-stream-usage-5x.txt](deepseek-stream-usage-5x.txt) |\n| 真实 OpenAI provider `stream_options.include_usage=True` 稳定性(可选 · 海外 / CI) | ⏸️ **可选** | 国内不可用 · 若海外或 CI 环境有 key 再跑 · 非 gate 必要项 |\n| 真实 Anthropic provider 流式降级(usage=None)| ⏸️ **可选** | 国内不可直连 · 非 gate 必要项(ADR-078 §决策一 已定 Anthropic 降级 usage=None 合法)|\n| 真实 Qwen provider 流式降级 | ⏸️ **可选** | 同上 · DASHSCOPE 可选补跑 |\n| 末块 usage 稳定返回 | ✅ **通过** | DeepSeek 5/5 runs 末块 usage 字段全部非 None · 单 chunk lookahead 机制兼容(router.py:_merge_usage_into_chunk)|\n\n---\n\n## §3 补跑流程(DeepSeek 主路径 · 国内默认)\n\n### §3.1 环境准备\n\n```bash\n# 加载 .env(DEEPSEEK_API_KEY 已配置 · 见 .env.example §LLM)\nset -a; source .env; set +a\n[ -n \"$DEEPSEEK_API_KEY\" ] && echo \"KEY_SET\" || echo \"KEY_MISSING\"\n\n# 确认 DeepSeek 端点可达\ncurl -sH \"Authorization: Bearer $DEEPSEEK_API_KEY\" \"$DEEPSEEK_BASE_URL/models\" | head -5\n\n# 验证 litellm 识别 DeepSeek 的 supported_openai_params\nuv run python -c \"from litellm import get_supported_openai_params; print(get_supported_openai_params(model='deepseek/deepseek-chat'))\"\n# 预期输出包含 'stream_options' · 若不含则 DeepSeek 走降级路径(usage=None 合法 · 不阻断 gate · 但需切其他 provider 才能过 stream_options 稳定性硬判据)\n```\n\n### §3.2 实测命令(DeepSeek 主路径)\n\n```bash\n# Step 1 · DeepSeek deepseek-chat 流式 + stream_options.include_usage=True\nuv run python -c \"\nimport asyncio\nfrom src.gateway.llm.router import LLMRouter\nfrom src.ports.llm import LLMRequest, LLMMessage\n\nasync def probe():\n router = LLMRouter()\n req = LLMRequest(\n messages=[LLMMessage(role='user', content='say hi')],\n model_id='deepseek/deepseek-chat',\n )\n chunks = [c async for c in router.route_stream(req)]\n last = chunks[-1]\n assert last.usage_tokens is not None, 'Stage 3 gate: last chunk must carry usage'\n assert last.prompt_tokens is not None\n assert last.completion_tokens is not None\n print(f'PASS · prompt={last.prompt_tokens} completion={last.completion_tokens} usage={last.usage_tokens}')\n\nasyncio.run(probe())\n\" 2>&1 | tee docs/evidence/adr-078-stage3/deepseek-stream-usage.txt\n\n# Step 2 · 连续跑 5 次稳定性(同一脚本循环)\nfor i in $(seq 1 5); do\n echo \"=== run $i ===\" >> docs/evidence/adr-078-stage3/deepseek-stream-usage-5x.txt\n uv run python -c \"...上述 probe 脚本...\" >> docs/evidence/adr-078-stage3/deepseek-stream-usage-5x.txt 2>&1\ndone\n\n# Step 3 · (可选)OpenAI 补跑 —— 仅海外 / CI 有 OPENAI_API_KEY 时\n# 若无 key 则跳过 · Stage 3 gate 以 DeepSeek 主路径通过为准\nif [ -n \"$OPENAI_API_KEY\" ]; then\n uv run python -c \"... model_id='gpt-4o-mini' ...\" | tee docs/evidence/adr-078-stage3/openai-stream-usage.txt\nfi\n```\n\n### §3.3 Gate 过判定\n\n**PASS 条件**(全部满足):\n1. 连续 5 次 **DeepSeek** 流式实测 · 末块 `usage_tokens/prompt_tokens/completion_tokens` 均非 None\n2. 退出码 0 · 无 `LLMProviderError` · 无 `ModelAccessDeniedError`\n3. (可选加分项)OpenAI / Anthropic / Qwen 降级行为实测 · 非 gate 必要项\n\n**FAIL 路径**(任一命中即 gate 未过):\n- DeepSeek `get_supported_openai_params` 返回不含 `stream_options` → 切换至 Qwen(DASHSCOPE)或海外 OpenAI 重跑\n- 末块 usage 字段缺失 / 为 None → 说明 provider 对 `include_usage` 支持不稳定 · 触发 `call_stream` 降级分支 · 记录现象后按 ADR-078 §Open Questions 处理\n\n### §3.4 证据登记\n\n补跑完成后 · 在本文件 §2.2 改 ❌→✅ · 更新 ADR-078 §Stage 3 gate 状态 · 回写 `packet.verification_results[+N]`。\n\n---\n\n## §4 当前合入判定(FD-03 D3 · 2026-04-25 gate 通过)\n\nPR #294 合入前置已满足(DeepSeek 5/5 稳定性实测 PASS):\n\n- ADR-078 §Stage 3 gate ✅ 通过(DeepSeek 主路径 · 5/5 runs)\n- `已通过` 状态与 evidence 一致(本文件 + ADR-078 §Stage 3 状态标注同步)\n- FD-03 D3 严格口径\"严格不合入\"条件(gate 未过)已解除\n- R3 advisory FAIL(CI docker 缺失 · 与本 PR 无关)+ GOV-01 DEFERRED(blocking_total=0)已独立解释 · 见 [docs/evidence/pr-294-gate-explain/](../pr-294-gate-explain/)\n- 可选补跑:OpenAI / Anthropic / Qwen 降级路径在海外或 CI 环境补跑(非必要)\n\n---\n\n## §5 历史证据\n\n- 2026-04-24 · `evidence/local/litellm-stream-options-probe-2026-04-24.md`(本地 gitignored · 记载 OpenAI quota 耗尽 · 国内路径不可达)\n- 2026-04-25 · Provider 策略重判 · 国内默认 DeepSeek(OpenAI 兼容协议)· ADR-078 Stage 3 gate 未硬锁 OpenAI 官方端点 · probe 脚本从 `gpt-4o-mini` 迁移至 `deepseek/deepseek-chat`\n"}, "35abb05dd2351148222eb4c2c3f39df8e65ae03a": {"t": 1785770616.8571715, "n": 5666, "h": "1551fb5ef497d2e9", "c": "# ADR-078 Stage 3 · 流式 Port Expand 实测证据(✅ 已通过 · DeepSeek 主路径)\n\n> **Status**: `✅ 已通过 — DeepSeek 5/5 稳定性 PASS · 2026-04-25`\n> **Gate**: [ADR-078 §Stage 3](../../adr/ADR-078-conversation-port-streaming.md#Stage-3) · `stream_options 稳定性实测通过`\n> **FD-03 裁决**: D3 口径解除 · 本 gate 通过 · PR #294 合入前置已满足\n> **Provider 策略**: 国内默认 DeepSeek(OpenAI 兼容协议 · 国内可直连)· OpenAI 可选(海外 / CI 环境)· Anthropic / Qwen 为降级验证\n> **证据**: [`deepseek-stream-usage-5x.txt`](deepseek-stream-usage-5x.txt) · 5/5 runs · 末块 usage=9 / prompt=7 / completion=2 / finish_reason=stop · 全部非 None\n\n---\n\n## §1 证据要求(gate 定义)\n\nADR-078 §Stage 3 对 PR #294 合入的硬约束:\n\n```\nStage 3 | 单原子 PR · Port Expand 全量闭环(决策二 8 项影响点)\n | `make preflight` 全绿 · `stream_options` 稳定性实测通过\n```\n\n**核心 gate**:`stream_options={\"include_usage\": True}` 在真实 OpenAI 系列 provider 下的稳定性实测。\n\n---\n\n## §2 当前证据状态(runtime_verified · 2026-04-25)\n\n### §2.1 已完成部分\n\n- ✅ **allowlist 前置校验**:unit 测试覆盖([test_route_stream_allowlist.py](../../../tests/unit/gateway/test_route_stream_allowlist.py))\n- ✅ **LLMProviderError 异常包装**:unit 测试覆盖([test_route_stream_provider_error.py](../../../tests/unit/gateway/test_route_stream_provider_error.py) `TestRouteStreamProviderError`)\n- ✅ **provider 分流 (supported_openai_params)**:unit 测试覆盖(同上 `TestRouteStreamProviderSplit`)\n- ✅ **末块 usage 合并**:unit 测试覆盖(同上 `test_openai_usage_only_tail_chunk_merged_*`)\n- ✅ **LLM_CALL audit 四态**:FD-03 F-HIGH-03 Phase C 新增(`TestRouteStreamAuditEvents`)\n- ✅ **mypy strict**:`src/gateway/llm/router.py` → Success no issues\n- ✅ **preflight-fast**:3262 passed · 2 pre-existing fail (alembic env · 非本 PR)\n\n### §2.2 **待补证部分**(Stage 3 核心 gate)\n\n| 项 | 状态 | 证据 / 原因 |\n|---|---|---|\n| 真实 **DeepSeek** provider `stream_options.include_usage=True` 稳定性(国内默认) | ✅ **通过** | 2026-04-25 · 5/5 runs · 末块 usage=9 / prompt=7 / completion=2 / finish_reason=stop · [deepseek-stream-usage-5x.txt](deepseek-stream-usage-5x.txt) |\n| 真实 OpenAI provider `stream_options.include_usage=True` 稳定性(可选 · 海外 / CI) | ⏸️ **可选** | 国内不可用 · 若海外或 CI 环境有 key 再跑 · 非 gate 必要项 |\n| 真实 Anthropic provider 流式降级(usage=None)| ⏸️ **可选** | 国内不可直连 · 非 gate 必要项(ADR-078 §决策一 已定 Anthropic 降级 usage=None 合法)|\n| 真实 Qwen provider 流式降级 | ⏸️ **可选** | 同上 · DASHSCOPE 可选补跑 |\n| 末块 usage 稳定返回 | ✅ **通过** | DeepSeek 5/5 runs 末块 usage 字段全部非 None · 单 chunk lookahead 机制兼容(router.py:_merge_usage_into_chunk)|\n\n---\n\n## §3 补跑流程(DeepSeek 主路径 · 国内默认)\n\n### §3.1 环境准备\n\n```bash\n# 加载 .env(DEEPSEEK_API_KEY 已配置 · 见 .env.example §LLM)\nset -a; source .env; set +a\n[ -n \"$DEEPSEEK_API_KEY\" ] && echo \"KEY_SET\" || echo \"KEY_MISSING\"\n\n# 确认 DeepSeek 端点可达\ncurl -sH \"Authorization: Bearer $DEEPSEEK_API_KEY\" \"$DEEPSEEK_BASE_URL/models\" | head -5\n\n# 验证 litellm 识别 DeepSeek 的 supported_openai_params\nuv run python -c \"from litellm import get_supported_openai_params; print(get_supported_openai_params(model='deepseek/deepseek-chat'))\"\n# 预期输出包含 'stream_options' · 若不含则 DeepSeek 走降级路径(usage=None 合法 · 不阻断 gate · 但需切其他 provider 才能过 stream_options 稳定性硬判据)\n```\n\n### §3.2 实测命令(DeepSeek 主路径)\n\n```bash\n# Step 1 · DeepSeek deepseek-chat 流式 + stream_options.include_usage=True\nuv run python -c \"\nimport asyncio\nfrom src.gateway.llm.router import LLMRouter\nfrom src.ports.llm import LLMRequest, LLMMessage\n\nasync def probe():\n router = LLMRouter()\n req = LLMRequest(\n messages=[LLMMessage(role='user', content='say hi')],\n model_id='deepseek/deepseek-chat',\n )\n chunks = [c async for c in router.route_stream(req)]\n last = chunks[-1]\n assert last.usage_tokens is not None, 'Stage 3 gate: last chunk must carry usage'\n assert last.prompt_tokens is not None\n assert last.completion_tokens is not None\n print(f'PASS · prompt={last.prompt_tokens} completion={last.completion_tokens} usage={last.usage_tokens}')\n\nasyncio.run(probe())\n\" 2>&1 | tee docs/evidence/adr-078-stage3/deepseek-stream-usage.txt\n\n# Step 2 · 连续跑 5 次稳定性(同一脚本循环)\nfor i in $(seq 1 5); do\n echo \"=== run $i ===\" >> docs/evidence/adr-078-stage3/deepseek-stream-usage-5x.txt\n uv run python -c \"...上述 probe 脚本...\" >> docs/evidence/adr-078-stage3/deepseek-stream-usage-5x.txt 2>&1\ndone\n\n# Step 3 · (可选)OpenAI 补跑 —— 仅海外 / CI 有 OPENAI_API_KEY 时\n# 若无 key 则跳过 · Stage 3 gate 以 DeepSeek 主路径通过为准\nif [ -n \"$OPENAI_API_KEY\" ]; then\n uv run python -c \"... model_id='gpt-4o-mini' ...\" | tee docs/evidence/adr-078-stage3/openai-stream-usage.txt\nfi\n```\n\n### §3.3 Gate 过判定\n\n**PASS 条件**(全部满足):\n1. 连续 5 次 **DeepSeek** 流式实测 · 末块 `usage_tokens/prompt_tokens/completion_tokens` 均非 None\n2. 退出码 0 · 无 `LLMProviderError` · 无 `ModelAccessDeniedError`\n3. (可选加分项)OpenAI / Anthropic / Qwen 降级行为实测 · 非 gate 必要项\n\n**FAIL 路径**(任一命中即 gate 未过):\n- DeepSeek `get_supported_openai_params` 返回不含 `stream_options` → 切换至 Qwen(DASHSCOPE)或海外 OpenAI 重跑\n- 末块 usage 字段缺失 / 为 None → 说明 provider 对 `include_usage` 支持不稳定 · 触发 `call_stream` 降级分支 · 记录现象后按 ADR-078 §Open Questions 处理\n\n### §3.4 证据登记\n\n补跑完成后 · 在本文件 §2.2 改 ❌→✅ · 更新 ADR-078 §Stage 3 gate 状态 · 回写 `packet.verification_results[+N]`。\n\n---\n\n## §4 当前合入判定(FD-03 D3 · 2026-04-25 gate 通过)\n\nPR #294 合入前置已满足(DeepSeek 5/5 稳定性实测 PASS):\n\n- ADR-078 §Stage 3 gate ✅ 通过(DeepSeek 主路径 · 5/5 runs)\n- `已通过` 状态与 evidence 一致(本文件 + ADR-078 §Stage 3 状态标注同步)\n- FD-03 D3 严格口径\"严格不合入\"条件(gate 未过)已解除\n- R3 advisory FAIL(CI docker 缺失 · 与本 PR 无关)+ GOV-01 DEFERRED(blocking_total=0)已独立解释 · 见 [docs/evidence/pr-294-gate-explain/](../pr-294-gate-explain/)\n- 可选补跑:OpenAI / Anthropic / Qwen 降级路径在海外或 CI 环境补跑(非必要)\n\n---\n\n## §5 历史证据\n\n- 2026-04-24 · `evidence/local/litellm-stream-options-probe-2026-04-24.md`(本地 gitignored · 记载 OpenAI quota 耗尽 · 国内路径不可达)\n- 2026-04-25 · Provider 策略重判 · 国内默认 DeepSeek(OpenAI 兼容协议)· ADR-078 Stage 3 gate 未硬锁 OpenAI 官方端点 · probe 脚本从 `gpt-4o-mini` 迁移至 `deepseek/deepseek-chat`\n"}}}}