# degoog - Doramagic AI Context Pack

> 定位：安装前体验与判断资产。它帮助宿主 AI 有一个好的开始，但不代表已经安装、执行或验证目标项目。

## 充分原则

- **充分原则，不是压缩原则**：AI Context Pack 应该充分到让宿主 AI 在开工前理解项目价值、能力边界、使用入口、风险和证据来源；它可以分层组织，但不以最短摘要为目标。
- **压缩策略**：只压缩噪声和重复内容，不压缩会影响判断和开工质量的上下文。

## 给宿主 AI 的使用方式

你正在读取 Doramagic 为 degoog 编译的 AI Context Pack。请把它当作开工前上下文：帮助用户理解适合谁、能做什么、如何开始、哪些必须安装后验证、风险在哪里。不要声称你已经安装、运行或执行了目标项目。

## Claim 消费规则

- **事实来源**：Repo Evidence + Claim/Evidence Graph；Human Wiki 只提供显著性、术语和叙事结构。
- **事实最低状态**：`supported`
- `supported`：可以作为项目事实使用，但回答中必须引用 claim_id 和证据路径。
- `weak`：只能作为低置信度线索，必须要求用户继续核实。
- `inferred`：只能用于风险提示或待确认问题，不能包装成项目事实。
- `unverified`：不得作为事实使用，应明确说证据不足。
- `contradicted`：必须展示冲突来源，不得替用户强行选择一个版本。

## 它最适合谁

- **正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**：README 或插件配置提到多个宿主 AI。 证据：`README.md` Claim：`clm_0002` supported 0.86

## 它能做什么

- **命令行启动或安装流程**（需要安装后验证）：项目文档中存在可执行命令，真实使用需要在本地或宿主环境中运行这些命令。 证据：`README.md` Claim：`clm_0001` supported 0.86

## 怎么开始

- `git clone https://github.com/degoog-org/degoog.git` 证据：`README.md` Claim：`clm_0003` supported 0.86

## 继续前判断卡

- **当前建议**：先做权限沙盒试用
- **为什么**：项目存在安装命令、宿主配置或本地写入线索，不建议直接进入主力环境，应先在隔离环境试装。

### 30 秒判断

- **现在怎么做**：先做权限沙盒试用
- **最小安全下一步**：先跑 Prompt Preview；若仍要安装，只在隔离环境试装
- **先别相信**：工具权限边界不能在安装前相信。
- **继续会触碰**：命令执行、宿主 AI 配置、本地环境或项目文件

### 现在可以相信

- **适合人群线索：正在使用 Claude/Codex/Cursor/Gemini 等宿主 AI 的开发者**（supported）：有 supported claim 或项目证据支撑，但仍不等于真实安装效果。 证据：`README.md` Claim：`clm_0002` supported 0.86
- **能力存在：命令行启动或安装流程**（supported）：可以相信项目包含这类能力线索；是否适合你的具体任务仍要试用或安装后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86
- **存在 Quick Start / 安装命令线索**（supported）：可以相信项目文档出现过启动或安装入口；不要因此直接在主力环境运行。 证据：`README.md` Claim：`clm_0003` supported 0.86

### 现在还不能相信

- **工具权限边界不能在安装前相信。**（unverified）：MCP/tool 类项目通常会触碰文件、网络、浏览器或外部 API，必须真实检查权限和日志。
- **真实输出质量不能在安装前相信。**（unverified）：Prompt Preview 只能展示引导方式，不能证明真实项目中的结果质量。
- **宿主 AI 版本兼容性不能在安装前相信。**（unverified）：Claude、Cursor、Codex、Gemini 等宿主加载规则和版本差异必须在真实环境验证。
- **不会污染现有宿主 AI 行为，不能直接相信。**（inferred）：Skill、plugin、AGENTS/CLAUDE/GEMINI 指令可能改变宿主 AI 的默认行为。 证据：`CLAUDE.md`
- **可安全回滚不能默认相信。**（unverified）：除非项目明确提供卸载和恢复说明，否则必须先在隔离环境验证。
- **真实安装后是否与用户当前宿主 AI 版本兼容？**（unverified）：兼容性只能通过实际宿主环境验证。
- **项目输出质量是否满足用户具体任务？**（unverified）：安装前预览只能展示流程和边界，不能替代真实评测。
- **安装命令是否需要网络、权限或全局写入？**（unverified）：这影响企业环境和个人环境的安装风险。 证据：`README.md`

### 继续会触碰什么

- **命令执行**：包管理器、网络下载、本地插件目录、项目配置或用户主目录。 原因：运行第一条命令就可能产生环境改动；必须先判断是否值得跑。 证据：`README.md`
- **宿主 AI 配置**：Claude/Codex/Cursor/Gemini/OpenCode 等宿主的 plugin、Skill 或规则加载配置。 原因：宿主配置会改变 AI 后续工作方式，可能和用户已有规则冲突。 证据：`CLAUDE.md`
- **本地环境或项目文件**：安装结果、插件缓存、项目配置或本地依赖目录。 原因：安装前无法证明写入范围和回滚方式，需要隔离验证。 证据：`README.md`
- **宿主 AI 上下文**：AI Context Pack、Prompt Preview、Skill 路由、风险规则和项目事实。 原因：导入上下文会影响宿主 AI 后续判断，必须避免把未验证项包装成事实。

### 最小安全下一步

- **先跑 Prompt Preview**：用安装前交互式试用判断工作方式是否匹配，不需要授权或改环境。（适用：任何项目都适用，尤其是输出质量未知时。）
- **只在隔离目录或测试账号试装**：避免安装命令污染主力宿主 AI、真实项目或用户主目录。（适用：存在命令执行、插件配置或本地写入线索时。）
- **先备份宿主 AI 配置**：Skill、plugin、规则文件可能改变 Claude/Cursor/Codex 的默认行为。（适用：存在插件 manifest、Skill 或宿主规则入口时。）
- **安装后只验证一个最小任务**：先验证加载、兼容、输出质量和回滚，再决定是否深用。（适用：准备从试用进入真实工作流时。）

### 退出方式

- **保留安装前状态**：记录原始宿主配置和项目状态，后续才能判断是否可恢复。
- **准备移除宿主 plugin / Skill / 规则入口**：如果试装后行为异常，可以把宿主 AI 恢复到试装前状态。
- **记录安装命令和写入路径**：没有明确卸载说明时，至少要知道哪些目录或配置需要手动清理。
- **如果没有回滚路径，不进入主力环境**：不可回滚是继续前阻断项，不应靠信任或运气继续。

## 哪些只能预览

- 解释项目适合谁和能做什么
- 基于项目文档演示典型对话流程
- 帮助用户判断是否值得安装或继续研究

## 哪些必须安装后验证

- 真实安装 Skill、插件或 CLI
- 执行脚本、修改本地文件或访问外部服务
- 验证真实输出质量、性能和兼容性

## 边界与风险判断卡

- **把安装前预览误认为真实运行**：用户可能高估项目已经完成的配置、权限和兼容性验证。 处理方式：明确区分 prompt_preview_can_do 与 runtime_required。 Claim：`clm_0004` inferred 0.45
- **命令执行会修改本地环境**：安装命令可能写入用户主目录、宿主插件目录或项目配置。 处理方式：先在隔离环境或测试账号中运行。 证据：`README.md` Claim：`clm_0005` supported 0.86
- **待确认**：真实安装后是否与用户当前宿主 AI 版本兼容？。原因：兼容性只能通过实际宿主环境验证。
- **待确认**：项目输出质量是否满足用户具体任务？。原因：安装前预览只能展示流程和边界，不能替代真实评测。
- **待确认**：安装命令是否需要网络、权限或全局写入？。原因：这影响企业环境和个人环境的安装风险。

## 开工前工作上下文

### 加载顺序

- 先读取 how_to_use.host_ai_instruction，建立安装前判断资产的边界。
- 读取 claim_graph_summary，确认事实来自 Claim/Evidence Graph，而不是 Human Wiki 叙事。
- 再读取 intended_users、capabilities 和 quick_start_candidates，判断用户是否匹配。
- 需要执行具体任务时，优先查 role_skill_index，再查 evidence_index。
- 遇到真实安装、文件修改、网络访问、性能或兼容性问题时，转入 risk_card 和 boundaries.runtime_required。

### 任务路由

- **命令行启动或安装流程**：先说明这是安装后验证能力，再给出安装前检查清单。 边界：必须真实安装或运行后验证。 证据：`README.md` Claim：`clm_0001` supported 0.86

### 上下文规模

- 文件总数：437
- 重要文件覆盖：40/437
- 证据索引条目：75
- 角色 / Skill 条目：3

### 证据不足时的处理

- **missing_evidence**：说明证据不足，要求用户提供目标文件、README 段落或安装后验证记录；不要补全事实。
- **out_of_scope_request**：说明该任务超出当前 AI Context Pack 证据范围，并建议用户先查看 Human Manual 或真实安装后验证。
- **runtime_request**：给出安装前检查清单和命令来源，但不要替用户执行命令或声称已执行。
- **source_conflict**：同时展示冲突来源，标记为待核实，不要强行选择一个版本。

## Prompt Recipes

### 适配判断

- 目标：判断这个项目是否适合用户当前任务。
- 预期输出：适配结论、关键理由、证据引用、安装前可预览内容、必须安装后验证内容、下一步建议。

```text
请基于 degoog 的 AI Context Pack，先问我 3 个必要问题，然后判断它是否适合我的任务。回答必须包含：适合谁、能做什么、不能做什么、是否值得安装、证据来自哪里。所有项目事实必须引用 evidence_refs、source_paths 或 claim_id。
```

### 安装前体验

- 目标：让用户在安装前感受核心工作流，同时避免把预览包装成真实能力或营销承诺。
- 预期输出：一段带边界标签的体验剧本、安装后验证清单和谨慎建议；不含真实运行承诺或强营销表述。

```text
请把 degoog 当作安装前体验资产，而不是已安装工具或真实运行环境。

请严格输出四段：
1. 先问我 3 个必要问题。
2. 给出一段“体验剧本”：用 [安装前可预览]、[必须安装后验证]、[证据不足] 三种标签展示它可能如何引导工作流。
3. 给出安装后验证清单：列出哪些能力只有真实安装、真实宿主加载、真实项目运行后才能确认。
4. 给出谨慎建议：只能说“值得继续研究/试装”“先补充信息后再判断”或“不建议继续”，不得替项目背书。

硬性边界：
- 不要声称已经安装、运行、执行测试、修改文件或产生真实结果。
- 不要写“自动适配”“确保通过”“完美适配”“强烈建议安装”等承诺性表达。
- 如果描述安装后的工作方式，必须使用“如果安装成功且宿主正确加载 Skill，它可能会……”这种条件句。
- 体验剧本只能写成“示例台词/假设流程”：使用“可能会询问/可能会建议/可能会展示”，不要写“已写入、已生成、已通过、正在运行、正在生成”。
- Prompt Preview 不负责给安装命令；如用户准备试装，只能提示先阅读 Quick Start 和 Risk Card，并在隔离环境验证。
- 所有项目事实必须来自 supported claim、evidence_refs 或 source_paths；inferred/unverified 只能作风险或待确认项。

```

### 角色 / Skill 选择

- 目标：从项目里的角色或 Skill 中挑选最匹配的资产。
- 预期输出：候选角色或 Skill 列表，每项包含适用场景、证据路径、风险边界和是否需要安装后验证。

```text
请读取 role_skill_index，根据我的目标任务推荐 3-5 个最相关的角色或 Skill。每个推荐都要说明适用场景、可能输出、风险边界和 evidence_refs。
```

### 风险预检

- 目标：安装或引入前识别环境、权限、规则冲突和质量风险。
- 预期输出：环境、权限、依赖、许可、宿主冲突、质量风险和未知项的检查清单。

```text
请基于 risk_card、boundaries 和 quick_start_candidates，给我一份安装前风险预检清单。不要替我执行命令，只说明我应该检查什么、为什么检查、失败会有什么影响。
```

### 宿主 AI 开工指令

- 目标：把项目上下文转成一次对话开始前的宿主 AI 指令。
- 预期输出：一段边界明确、证据引用明确、适合复制给宿主 AI 的开工前指令。

```text
请基于 degoog 的 AI Context Pack，生成一段我可以粘贴给宿主 AI 的开工前指令。这段指令必须遵守 not_runtime=true，不能声称项目已经安装、运行或产生真实结果。
```

## 角色 / Skill 索引

- 共索引 3 个角色 / Skill / 项目文档条目。

- **Run**（project_doc）：Search aggregator that queries multiple engines and shows results in one place. You can add custom search engines, bang-command plugins, slot plugins query-triggered panels above/below results or in the sidebar , and transports custom HTTP fetch strategies like curl, FlareSolverr, or your own . The dream would be to eventually have a user made marketplace for plugins/engines. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`README.md`
- **Hi, fccview here!**（project_doc）：Not sure what you were hoping to find here, there's no AI directive because this is not a AI made app. That said I understand that in 2026 we need to be lenient so there's no reason to flat out reject software only because it was AI assisted. AI is a powerful tool that used properly can boost productivity. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CLAUDE.md`
- **Some basic rules**（project_doc）：- Fork develop and branch off it. Pull requests MUST be directed to the develop branch. - For customisation and extensions, see the documentation docs/index.html . For adding built-in engines or bang commands, follow the patterns in src/server/extensions/engines and src/server/extensions/commands/builtins . - If you use AI, ensure your code is reviewed, meets the coding standards below, and is not overly engineered. 激活提示：当用户需要理解项目结构、安装方式或边界时参考。 证据：`CONTRIBUTING.md`

## 证据索引

- 共索引 75 条证据。

- **Run**（documentation）：Search aggregator that queries multiple engines and shows results in one place. You can add custom search engines, bang-command plugins, slot plugins query-triggered panels above/below results or in the sidebar , and transports custom HTTP fetch strategies like curl, FlareSolverr, or your own . The dream would be to eventually have a user made marketplace for plugins/engines. 证据：`README.md`
- **Package**（package_manifest）：{ "name": "degoog", "version": "0.22.0", "type": "module", "scripts": { "dev": "bun run --watch src/server/index.ts", "build": "bun run build.ts", "build:watch": "bun run build.ts --watch", "stop": "kill $ lsof -t -i:4444 ", "start": "bun run src/server/index.ts", "start:dev": "DEGOOG PORT=4445 bun run src/server/index.ts --debug", "develop": "yarn build:watch; yarn run stop; yarn run start:dev", "typecheck": "tsc --noEmit", "lint": "eslint src/ tests/", "lint:fix": "eslint src/ tests/ --fix", "test": "LOG LEVEL= DEGOOG SETTINGS PATH= bun test $ find tests -name ' .test.ts' ! -path ' /stress/ ' sort tr '\\n' ' ' ", "test:rate-limit": "LOG LEVEL=debug bun test tests/stress/" }, "dependencies… 证据：`package.json`
- **Hi, fccview here!**（documentation）：Not sure what you were hoping to find here, there's no AI directive because this is not a AI made app. That said I understand that in 2026 we need to be lenient so there's no reason to flat out reject software only because it was AI assisted. AI is a powerful tool that used properly can boost productivity. 证据：`CLAUDE.md`
- **Some basic rules**（documentation）：- Fork develop and branch off it. Pull requests MUST be directed to the develop branch. - For customisation and extensions, see the documentation docs/index.html . For adding built-in engines or bang commands, follow the patterns in src/server/extensions/engines and src/server/extensions/commands/builtins . - If you use AI, ensure your code is reviewed, meets the coding standards below, and is not overly engineered. 证据：`CONTRIBUTING.md`
- **License**（source_file）：GNU AFFERO GENERAL PUBLIC LICENSE Version 3, 19 November 2007 证据：`LICENSE`
- **Fr Fr**（structured_config）：{ "settings-page": { "meta": { "title": "Paramètres – degoog", "description": "Paramètres de recherche degoog." }, "back": "Retour", "page-title": "Paramètres", "nav": { "aria-section": "Section des paramètres", "aria-sections": "Sections des paramètres", "general": "Général", "server": "Serveur", "engines": "Moteurs", "plugins": "Plugins", "transports": "Transports", "themes": "Thèmes", "store": "Boutique", "indexer": "Indexeur Degoog", "shortcuts": "Raccourcis" }, "tab-search": { "no-results": "Aucun résultat" }, "appearance": { "heading": "Apparence", "desc": "Choisissez le thème souhaité.", "save-defaults": "Enregistrer comme valeur pa… 证据：`src/locales/fr-FR.json`
- **He**（structured_config）：{ "settings-page": { "meta": { "title": "הגדרות - degoog", "description": "הגדרות חיפוש degoog" }, "back": "חזרה", "page-title": "הגדרות", "nav": { "aria-section": "אזור הגדרות", "aria-sections": "אזורי הגדרות", "general": "כללי", "server": "שרת", "engines": "מנועים", "plugins": "תוספים", "transports": "דרכי העברה", "themes": "ערכות נושא", "store": "חנות", "shortcuts": "קיצורים" }, "tab-search": { "no-results": "אין תוצאות" }, "appearance": { "heading": "מראה", "desc": "בחר את העיצוב המועדף עליך.", "save-defaults": "שמור כברירת מחדל עבור המופע" }, "theme": { "system": "ברירת מחדל של המערכת", "light": "בהיר", "dark": "כהה" }, "search-options": { "heading":… 证据：`src/locales/he.json`
- **It**（structured_config）：{ "settings-page": { "meta": { "title": "Impostazioni – degoog", "description": "Impostazioni per degoog." }, "back": "Ritorna", "page-title": "Impostazioni", "nav": { "aria-section": "Sezione impostazioni", "aria-sections": "Sezioni impostazioni", "general": "Generale", "server": "Server", "engines": "Motori", "plugins": "Plugin", "transports": "Trasporti", "themes": "Temi", "store": "Negozio", "shortcuts": "Scorciatoie" }, "tab-search": { "no-results": "Nessun risultato" }, "appearance": { "heading": "Aspetto", "desc": "Scegli il tema preferito.", "save-defaults": "Salva come predefinito dell’istanza" }, "theme": { "system": "Predefinito di si… 证据：`src/locales/it.json`
- **Fr Fr**（structured_config）：{ "app": { "title": "degoog", "name": "Degoog", "description": "degoog est un agrégateur de moteurs de recherche alternatif." }, "index-templates": { "footer": { "repo": "repo", "docs": "docs" }, "header": { "settings-title": "Paramètres" }, "search": { "search-button": "Recherche degoog", "feeling-lucky": "J'ai de la Chance", "feeling-curious": "Je suis Curieux", "feeling-adventurous": "Je suis Aventurier", "feeling-playful": "Je suis Joueur", "feeling-stellar": "Je suis Stellaire", "feeling-trendy": "Je suis Tendance" } }, "search-templates": { "at-a-glance": { "found-on": "Trouvé sur : {sources text}" }, "tabs": { "web": "Web", "images": "Images", "videos": "Vidéos", "news": "Actualités"… 证据：`src/public/themes/degoog-theme/locales/fr-FR.json`
- **He**（structured_config）：{ "app": { "title": "degoog", "name": "degoog", "description": "degoog הוא אגרגטור מנועי חיפוש אלטרנטיבי." }, "index-templates": { "footer": { "repo": "מאגר", "docs": "תיעוד" }, "header": { "settings-title": "הגדרות" }, "search": { "search-button": "חיפוש degoog", "feeling-lucky": "יותר מזל משכל", "feeling-curious": "אני מרגיש סקרן", "feeling-adventurous": "אני מרגיש הרפתקני", "feeling-playful": "אני מרגיש שובב", "feeling-stellar": "אני מרגיש כוכבי", "feeling-trendy": "אני מרגיש טרנדי" } }, "search-templates": { "at-a-glance": { "found-on": "נמצא ב-: {sources text}" }, "tabs": { "web": "אינטרנט", "images": "תמונות", "videos": "סרטונים", "news": "חדשות", "options": "אפשרויות", "time": "זמן",… 证据：`src/public/themes/degoog-theme/locales/he.json`
- **It**（structured_config）：{ "app": { "title": "degoog", "name": "Degoog", "description": "degoog è un aggregatore alternativo di motori di ricerca." }, "index-templates": { "footer": { "repo": "repo", "docs": "docs" }, "header": { "settings-title": "Impostazioni" }, "search": { "search-button": "Cerca con degoog", "feeling-lucky": "Mi sento fortunato", "feeling-curious": "Mi sento curioso", "feeling-adventurous": "Mi sento avventuroso", "feeling-playful": "Mi sento giocoso", "feeling-stellar": "Mi sento stellare", "feeling-trendy": "Mi sento alla moda" } }, "search-templates": { "at-a-glance": { "found-on": "Trovato su: {sources text}" }, "tabs": { "web": "Web", "images": "Immagini", "videos": "Video", "news": "Noti… 证据：`src/public/themes/degoog-theme/locales/it.json`
- **En**（structured_config）：{ "at-a-glance": { "found-on": "Found on: {sources text}", "description": "Shows a quick preview of the top search result" } } 证据：`src/server/extensions/commands/builtins/at-a-glance/locales/en.json`
- **Fr**（structured_config）：{ "at-a-glance": { "found-on": "Trouvé sur : {sources text}", "description": "Aperçu rapide du premier résultat de recherche" } } 证据：`src/server/extensions/commands/builtins/at-a-glance/locales/fr.json`
- **He**（structured_config）：{ "at-a-glance": { "found-on": "נמצא ב: {sources text}", "description": "מציג תצוגה מקדימה מהירה של תוצאת החיפוש העליונה" } } 证据：`src/server/extensions/commands/builtins/at-a-glance/locales/he.json`
- **It**（structured_config）：{ "at-a-glance": { "found-on": "Trovato su: {sources text}", "description": "Mostra un'anteprima rapida del primo risultato di ricerca" } } 证据：`src/server/extensions/commands/builtins/at-a-glance/locales/it.json`
- **En**（structured_config）：{ "help": { "description": "List all available bang commands", "title": "Available Commands", "search-placeholder": "Search commands...", "aliases": "Aliases: {aliases}", "prefix-hint": "Search with a type prefix: {types}", "category-other": "Other" } } 证据：`src/server/extensions/commands/builtins/help/locales/en.json`
- **Fr**（structured_config）：{ "help": { "description": "Lister toutes les commandes bang disponibles", "title": "Commandes disponibles", "search-placeholder": "Rechercher des commandes...", "aliases": "Alias : {aliases}", "prefix-hint": "Rechercher avec un préfixe de type : {types}", "category-other": "Autre" } } 证据：`src/server/extensions/commands/builtins/help/locales/fr.json`
- **He**（structured_config）：{ "help": { "description": "רשימה של כל פקודות ה-bang הזמינות", "title": "פקודות זמינות", "search-placeholder": "חיפוש פקודות...", "aliases": "כינויים: {aliases}", "prefix-hint": "חיפוש עם קידומת סוג: {types}", "category-other": "אחר" } } 证据：`src/server/extensions/commands/builtins/help/locales/he.json`
- **It**（structured_config）：{ "help": { "description": "Elenca tutti i comandi bang disponibili", "title": "Comandi disponibili", "search-placeholder": "Cerca comandi...", "aliases": "Alias: {aliases}", "prefix-hint": "Cerca con un prefisso di tipo: {types}", "category-other": "Altro" } } 证据：`src/server/extensions/commands/builtins/help/locales/it.json`
- **En**（structured_config）：{ "ip": { "title": "IP Lookup", "description": "Look up IP address information", "title-result": "IP Info: {ip}", "detecting": "Detecting your IP...", "detect-failed": "Could not detect IP.", "detect-failed-hint": "Could not detect your public IP. Try !ip 8.8.8.8 ", "lookup-failed": "Lookup failed: {message}", "fetch-failed": "Failed to fetch IP data. Please try again.", "label-ip": "IP", "label-city": "City", "label-region": "Region", "label-country": "Country", "label-isp": "ISP", "label-org": "Org", "label-latlon": "Lat/Lon", "na": "N/A" } } 证据：`src/server/extensions/commands/builtins/ip/locales/en.json`
- **Fr**（structured_config）：{ "ip": { "title": "Recherche IP", "description": "Rechercher les informations d'une adresse IP", "title-result": "Info IP : {ip}", "detecting": "Détection de votre IP...", "detect-failed": "Impossible de détecter l'IP.", "detect-failed-hint": "Impossible de détecter votre IP publique. Essayez !ip 8.8.8.8 ", "lookup-failed": "Échec de la recherche : {message}", "fetch-failed": "Impossible de récupérer les données IP. Veuillez réessayer.", "label-ip": "IP", "label-city": "Ville", "label-region": "Région", "label-country": "Pays", "label-isp": "FAI", "label-org": "Organisation", "label-latlon": "Lat/Lon", "na": "N/D" } } 证据：`src/server/extensions/commands/builtins/ip/locales/fr.json`
- **He**（structured_config）：{ "ip": { "title": "חיפוש IP", "description": "חיפוש מידע על כתובת IP", "title-result": "מידע IP: {ip}", "detecting": "מזהה את ה-IP שלך...", "detect-failed": "לא ניתן היה לזהות IP.", "detect-failed-hint": "לא ניתן היה לזהות את ה-IP הציבורי שלך. נסה !ip 8.8.8.8 ", "lookup-failed": "החיפוש נכשל: {message}", "fetch-failed": "נכשל ניסיון הבאת נתוני IP. אנא נסה שוב.", "label-ip": "IP", "label-city": "עיר", "label-region": "אזור", "label-country": "מדינה", "label-isp": "ספק אינטרנט", "label-org": "ארגון", "label-latlon": "קו רוחב/אורך", "na": "לא זמין" } } 证据：`src/server/extensions/commands/builtins/ip/locales/he.json`
- **It**（structured_config）：{ "ip": { "title": "Ricerca IP", "description": "Cerca informazioni su un indirizzo IP", "title-result": "Info IP: {ip}", "detecting": "Rilevamento IP in corso...", "detect-failed": "Impossibile rilevare l’IP.", "detect-failed-hint": "Impossibile rilevare il tuo IP pubblico. Prova !ip 8.8.8.8 ", "lookup-failed": "Ricerca non riuscita: {message}", "fetch-failed": "Impossibile recuperare i dati IP. Riprova.", "label-ip": "IP", "label-city": "Città", "label-region": "Regione", "label-country": "Paese", "label-isp": "ISP", "label-org": "Organizzazione", "label-latlon": "Lat/Lon", "na": "N/D" } } 证据：`src/server/extensions/commands/builtins/ip/locales/it.json`
- **En**（structured_config）：{ "speedtest": { "title": "Speed Test", "description": "Run an internet speed test", "download": "Download Mbps ", "upload": "Upload Mbps ", "latency": "Latency ms ", "starting": "Starting...", "testing-latency": "Testing latency...", "testing-download": "Testing download speed...", "testing-upload": "Testing upload speed...", "complete": "Complete", "error": "Error" } } 证据：`src/server/extensions/commands/builtins/speedtest/locales/en.json`
- **Fr**（structured_config）：{ "speedtest": { "title": "Test de débit", "description": "Lancer un test de débit internet", "download": "Téléchargement Mbps ", "upload": "Envoi Mbps ", "latency": "Latence ms ", "starting": "Démarrage...", "testing-latency": "Test de latence...", "testing-download": "Test de débit descendant...", "testing-upload": "Test de débit montant...", "complete": "Terminé", "error": "Erreur" } } 证据：`src/server/extensions/commands/builtins/speedtest/locales/fr.json`
- **He**（structured_config）：{ "speedtest": { "title": "בדיקת מהירות", "description": "הפעל בדיקת מהירות אינטרנט", "download": "הורדה Mbps ", "upload": "העלאה Mbps ", "latency": "שיהוי ms ", "starting": "מתחיל...", "testing-latency": "בודק שיהוי...", "testing-download": "בודק מהירות הורדה...", "testing-upload": "בודק מהירות העלאה...", "complete": "הושלם", "error": "שגיאה" } } 证据：`src/server/extensions/commands/builtins/speedtest/locales/he.json`
- **It**（structured_config）：{ "speedtest": { "title": "Test di velocità", "description": "Esegui un test di velocità della connessione", "download": "Download Mbps ", "upload": "Upload Mbps ", "latency": "Latenza ms ", "starting": "Avvio...", "testing-latency": "Misurazione latenza...", "testing-download": "Test velocità di download...", "testing-upload": "Test velocità di upload...", "complete": "Completato", "error": "Errore" } } 证据：`src/server/extensions/commands/builtins/speedtest/locales/it.json`
- **En**（structured_config）：{ "uuid": { "title": "Generated UUIDs", "description": "Generate random UUIDs v4 default 10, or specify a number ", "copy": "Copy" } } 证据：`src/server/extensions/commands/builtins/uuid/locales/en.json`
- **Fr**（structured_config）：{ "uuid": { "title": "UUIDs générés", "description": "Générer des UUIDs v4 aléatoires 10 par défaut, ou spécifiez un nombre ", "copy": "Copier" } } 证据：`src/server/extensions/commands/builtins/uuid/locales/fr.json`
- **He**（structured_config）：{ "uuid": { "title": "UUIDs שנוצרו", "description": "צור UUIDs v4 אקראיים ברירת מחדל 10, או ציין מספר ", "copy": "העתק" } } 证据：`src/server/extensions/commands/builtins/uuid/locales/he.json`
- **It**（structured_config）：{ "uuid": { "title": "UUID generati", "description": "Genera UUID v4 casuali predefinito 10, oppure indica un numero ", "copy": "Copia" } } 证据：`src/server/extensions/commands/builtins/uuid/locales/it.json`
- **En**（structured_config）：{ "wikipedia": { "name": "Wikipedia", "description": "Shows a Wikipedia summary card in the sidebar when the search query matches an article.", "view-on-wikipedia": "Wikipedia ↗" } } 证据：`src/server/extensions/commands/builtins/wikipedia/locales/en.json`
- **Fr**（structured_config）：{ "wikipedia": { "name": "Wikipédia", "description": "Affiche une carte récapitulative Wikipédia dans la barre latérale lorsque la requête de recherche correspond à un article.", "read-more": "Wikipédia ↗" } } 证据：`src/server/extensions/commands/builtins/wikipedia/locales/fr.json`
- **He**（structured_config）：{ "wikipedia": { "name": "ויקיפדיה", "description": "מציג כרטיס סיכום של ויקיפדיה בסרגל הצד כאשר שאילתת החיפוש תואמת לערך.", "view-on-wikipedia": "צפה בוויקיפדיה ↗" } } 证据：`src/server/extensions/commands/builtins/wikipedia/locales/he.json`
- **It**（structured_config）：{ "wikipedia": { "name": "Wikipedia", "description": "Mostra una scheda riassuntiva di Wikipedia nella barra laterale quando la query di ricerca corrisponde a un articolo.", "read-more": "Wikipedia ↗" } } 证据：`src/server/extensions/commands/builtins/wikipedia/locales/it.json`
- **Simple**（source_file）：services: degoog: image: ghcr.io/degoog-org/degoog:latest volumes: - ./data:/app/data ports: - "4444:4444" restart: unless-stopped environment: DEGOOG SETTINGS PASSWORDS: "REPLACE WITH A STRONG PASSWORD" DEGOOG PUBLIC INSTANCE: "false" 证据：`docker-compose-examples/simple.yml`
- **Docker Compose**（source_file）：services: degoog: image: ghcr.io/degoog-org/degoog:latest volumes: - ./data:/app/data ports: - "4444:4444" restart: unless-stopped 证据：`docker-compose.yml`
- **Entrypoint**（source_file）：PUID=${PUID:-1000} PGID=${PGID:-1000} mkdir -p /app/data chown -R ${PUID}:${PGID} /app/data exec su-exec ${PUID}:${PGID} bun run src/server/index.ts 证据：`entrypoint.sh`
- **Skeleton**（source_file）：export const skeletonImageGrid = cols = 4, rows = 6 : string = export const skeletonVideoGrid = count = 12 : string = const skeletonCard = : string export const skeletonResults = count = 5 : string export const skeletonGlance = : string export const skeletonSidebar = : string export const skeletonFeedCards = count = 4 : string 证据：`src/client/animations/skeleton.ts`
- **Render Sidebar**（source_file）：import { state } from "../../state"; import type { SearchResponse, SlotPanel } from "../../types"; import { escapeHtml } from "../../utils/dom"; import { retryEngine } from "../../utils/search-actions"; import { engineCountHtml } from "../../utils/search/engine-failure"; ⋮---- export const setupRetryLinks = container: HTMLElement : void = export const sidebarAccordion = title: string, content: string : string const relatedSearchesHtml = terms: string : string const wireSidebar = sidebar: HTMLElement, onRelatedSearch: q: string = void, : void = export function renderSidebarSuggestions terms: string , onRelatedSearch: q: string = void, : void export function renderSidebar data: SearchResponse… 证据：`src/client/modules/renderer/render-sidebar.ts`
- **Render**（source_file）：import { MAX PAGE } from "../../constants"; import { state } from "../../state"; import type { ScoredResult } from "../../types"; import { cleanUrl } from "../../utils/dom"; import { buildPaginationHtml } from "../../utils/pagination"; import { goToPage } from "../../utils/search-actions"; import { renderTemplate } from "../../utils/template"; import { attachFaviconFallback } from "../../utils/favicon"; import { faviconHostname, faviconUrl } from "../../utils/url"; import { isImageSearchType } from "../../utils/engines"; import { getBase } from "../../utils/base-url"; import { destroyMediaObserver, setupMediaObserver } from "../media/media"; import { renderImageGrid } from "./render-media";… 证据：`src/client/modules/renderer/render.ts`
- **Tab Search**（source_file）：import { skeletonImageGrid, skeletonResults, skeletonSidebar } from "../../animations/skeleton"; import { state } from "../../state"; import { SlotPanelPosition, type ScoredResult, type SearchResponse, } from "../../types"; import { hideAcDropdown } from "../../utils/autocomplete"; import { isImageSearchType } from "../../utils/engines"; import { setActiveTab } from "../../utils/navigation"; import { fetchStreamingConfig } from "../../utils/streaming-config"; import { buildPaginationHtml } from "../../utils/pagination"; import { fetchGlancePanels, fetchSlotPanels } from "../../utils/search-utils"; import { abortStreamingSearch, performStreamingSearch, } from "../../utils/streaming-search";… 证据：`src/client/modules/tabs/tab-search.ts`
- **Steps**（source_file）：import type { PopoverAnchor } from "./dom"; export interface WizardStepLink { href: string; labelKey: string; } export interface WizardStep { tab?: string; selector?: string; titleKey: string; bodyKey: string; hintKey?: string; onEnter?: = void Promise ; navigateOnNext?: = string null; interactive?: boolean; popoverAnchor?: PopoverAnchor; liveCountSelector?: string; requireMin?: number; link?: WizardStepLink; } const setStoreFilter = value: string : void = const settingsHref = : string null = ⋮---- const storeInstallStep = type: string, titleKey: string, bodyKey: string, hintKey?: string, extras: Partial = {}, : WizardStep = 证据：`src/client/modules/wizard/steps.ts`
- **Render**（source_file）：import { escapeHtml } from "../../utils/dom"; import { SERVER SETTINGS PRESETS } from "./presets"; ⋮---- const h = headingKey: string, icon: string : string const desc = key: string : string const renderPresetSection = : string = ${ h "settings-page.server.presets.heading", "fa-solid fa-sliders" } ${ desc "settings-page.server.presets.desc" } ${escapeHtml t "settings-page.server.presets.select-label" } ${escapeHtml t "settings-page.server.presets.select-placeholder" } ${SERVER SETTINGS PRESETS.map preset const toggle = id: string, labelKey: string, opts: { aria?: string; title?: string; checked?: boolean } = {}, : string = const renderCacheSection = : string const renderApiKeySection = : st… 证据：`src/client/settings/server/render.ts`
- **Render**（source_file）：import { escapeHtml } from "../../utils/dom"; import { screenshotUrl } from "./lightbox"; import type { RepoInfo, StoreItem } from "../../types/store-tab"; import { getBase } from "../../utils/base-url"; import { renderMdInline } from "../../utils/md"; import { bindingParts } from "../../shortcuts/binding"; ⋮---- export function normalizeRepoUrl url: string : string export function formatRelativeTime iso: string : string export function repoImageSrc repo: RepoInfo, getToken: = string null, : string export function pluginTypeLabel type: string : string export function engineTypeLabel type: string : string export function renderRepoDetail repo: RepoInfo, getToken: = string null, statusByUrl:… 证据：`src/client/settings/store/render.ts`
- **Extension**（source_file）：export type SettingFieldType = "text" "number" "password" "url" "toggle" "textarea" "select" "urllist" "list" "info"; export interface SettingField { key: string; label: string; type: SettingFieldType; required?: boolean; placeholder?: string; description?: string; secret?: boolean; options?: string ; optionLabels?: string ; default?: string; advanced?: boolean; visibleWhen?: { key: string; equals: string }; itemSchema?: SettingField ; addLabel?: string; } export interface ExtensionMeta { id: string; displayName: string; description: string; primaryType?: string; searchTypes?: string ; type: string; trigger?: string; configurable: boolean; settingsSchema: SettingField ; settings: Record ; s… 证据：`src/client/types/extension.ts`
- **Pagination**（source_file）：export const buildPaginationHtml = totalPages: number, activePage: number, : string = 证据：`src/client/utils/pagination.ts`
- **Search Actions Page**（source_file）：import { skeletonImageGrid, skeletonResults, } from "../../animations/skeleton"; import { getEngines, isImageSearchType } from "../engines"; import { state } from "../../state"; import { buildSearchBody, buildSearchUrl } from "../url"; import { searchAuthHeaders, appendSearchAuthParams } from "../request"; import { getBase } from "../base-url"; import type { SearchResponse } from "../../types"; import { renderResults } from "../../modules/renderer/render"; import { fetchGlancePanels, fetchSlotPanels } from "../search-utils"; import { setResultsMeta } from "../search-helpers"; export async function goToPage pageNum: number : Promise 证据：`src/client/utils/search/search-actions-page.ts`
- **Search Actions Render**（source_file）：import { skeletonGlance, skeletonImageGrid, skeletonResults, skeletonSidebar, } from "../../animations/skeleton"; import { closeMediaPreview } from "../../modules/media/media"; import { clearSlotPanels, renderResults, renderSidebar, renderSidebarSuggestions, prependKnowledgePanels, } from "../../modules/renderer/render"; import { renderMediaEngineBar } from "../../modules/renderer/render-media"; import { state } from "../../state"; import { SlotPanelPosition, type SearchResponse } from "../../types"; import { abortAcReq, hideAcDropdown } from "../autocomplete"; import { setActiveTab, showAllTabs } from "../navigation"; import { setResultsMeta } from "../search-helpers"; import { abortGlance… 证据：`src/client/utils/search/search-actions-render.ts`
- **Index**（source_file）：import { SlotPanelPosition, TranslateFunction, type PluginContext, type SettingField, type ScoredResult, type SlotPlugin, } from "../../../../types"; import { asString, getSettings, isDisabled, } from "../../../../utils/plugin-settings"; import { useCache, type AsyncTtlCache } from "../../../../utils/cache"; import { escapeHtml, looksLikeProse, stripSnippetPrefix, } from "../../../../utils/text"; import { getRandomUserAgent } from "../../../../utils/user-agents"; import { logger } from "../../../../utils/logger"; ⋮---- const isWikipediaUrl = url: string : boolean = const scoreSnippet = snippet: string, queryTerms: string : number = const pickBestResult = results: ScoredResult , excludeWikip… 证据：`src/server/extensions/commands/builtins/at-a-glance/index.ts`
- **Index**（source_file）：import { TranslateFunction, type BangCommand, type CommandResult, type PluginContext, } from "../../../../types"; import { getCustomEngineTypes } from "../../../engines/registry"; import { getFilteredCommandRegistry } from "../../registry"; import { escapeHtml } from "../../../../utils/text"; ⋮---- get description : string ⋮---- init ctx: PluginContext : void async execute : Promise 证据：`src/server/extensions/commands/builtins/help/index.ts`
- **Template**（source_file）：{{prefixHint}} {{tabButtons}} {{panels}} function { var tabs=document.querySelectorAll '.help-tab' ; var panels=document.querySelectorAll '.help-panel' ; tabs.forEach function t { t.addEventListener 'click',function { tabs.forEach function x {x.classList.remove 'active' } ; panels.forEach function x {x.classList.remove 'active' } ; t.classList.add 'active' ; var p=document.querySelector ' data-help-panel="'+t.dataset.helpCat+'" ' ; if p p.classList.add 'active' ; } ; } ; var input=document.getElementById 'help-search-input' ; if input input.addEventListener 'input',function { var q=input.value.toLowerCase .trim ; var rows=document.querySelectorAll '.help-row' ; var counts={}; rows.forEach f… 证据：`src/server/extensions/commands/builtins/help/template.html`
- **Index**（source_file）：import { TranslateFunction, type BangCommand, type CommandContext, type CommandResult, } from "../../../../types"; import { getBaseUrl } from "../../../../utils/base-url"; import { outgoingFetch } from "../../../../utils/outgoing"; import { logger } from "../../../../utils/logger"; import { escapeHtml } from "../../../../utils/text"; ⋮---- get description : string ⋮---- async execute args: string, context?: CommandContext, : Promise 证据：`src/server/extensions/commands/builtins/ip/index.ts`
- **Index**（source_file）：import { readFileSync } from "fs"; import { dirname, join } from "path"; import { fileURLToPath } from "url"; import { TranslateFunction, type BangCommand, type CommandResult, } from "../../../../types"; ⋮---- get description : string ⋮---- async execute : Promise 证据：`src/server/extensions/commands/builtins/speedtest/index.ts`
- **Index**（source_file）：import { TranslateFunction, type BangCommand, type CommandResult, } from "../../../../types"; ⋮---- get description : string ⋮---- async execute args: string : Promise 证据：`src/server/extensions/commands/builtins/uuid/index.ts`
- **Index**（source_file）：import { SlotPanelPosition, TranslateFunction, type PluginContext, type SettingField, type SlotPlugin, type SlotPluginContext, } from "../../../../types"; import type { AsyncTtlCache } from "../../../../utils/cache"; import { getSettings } from "../../../../utils/plugin-settings"; import { logger } from "../../../../utils/logger"; ⋮---- export const toWikiDomain = raw: unknown : string = const wikiDomain = async : Promise = ⋮---- function escapeHtml s: string : string interface WikiPage { title: string; description: string; extract: string; thumbnail?: { source: string; isLogo?: boolean }; fullurl?: string; pageid: number; wikibase item?: string; } ⋮---- const proxyImageUrl = url: string :… 证据：`src/server/extensions/commands/builtins/wikipedia/index.ts`
- **Style**（source_file）：.wiki-card { .wiki-thumb { .wiki-thumb--logo { .wiki-body { .wiki-title { .wiki-title:hover { .wiki-desc { .wiki-extract { .wiki-footer-link { .wiki-footer-link:hover { 证据：`src/server/extensions/commands/builtins/wikipedia/style.css`
- **Template**（source_file）：{{thumbnail}} {{title}} {{description}} {{extract}} {{t:wikipedia.view-on-wikipedia}} 证据：`src/server/extensions/commands/builtins/wikipedia/template.html`
- **Index**（source_file）：import type { EngineContext, SearchResult } from "../../../../types"; import { DEGOOG ENGINE NAME, getKnownTypes, queryIndex, } from "../../../../indexer/store"; import { asBoolean } from "../../../../utils/plugin-settings"; import { getInstanceSettings } from "../../../../utils/server-settings"; ⋮---- const isIndexerOn = async : Promise = export const type = async : Promise = class DegoogEngine ⋮---- async executeSearch query: string, page?: number, timeFilter?: string, context?: EngineContext, : Promise 证据：`src/server/extensions/engines/builtins/degoog/index.ts`
- **Index**（source_file）：import { resolve, relative } from "path"; import { getStoreDir, normalizeRepoUrl } from "./persistence"; import { slugFromUrl } from "./repo-ops"; ⋮---- export function getStoreDirPath : string export function getRepoSlugFromUrl url: string : string export function resolveScreenshotPath repoSlug: string, itemPath: string, filename: string, : string null export function resolveRepoAssetPath repoSlug: string, relativePath: string, : string null 证据：`src/server/extensions/store/index.ts`
- 其余 15 条证据见 `AI_CONTEXT_PACK.json` 或 `EVIDENCE_INDEX.json`。

## 宿主 AI 必须遵守的规则

- **把本资产当作开工前上下文，而不是运行环境。**：AI Context Pack 只包含证据化项目理解，不包含目标项目的可执行状态。 证据：`README.md`, `package.json`, `CLAUDE.md`
- **回答用户时区分可预览内容与必须安装后才能验证的内容。**：安装前体验的消费者价值来自降低误装和误判，而不是伪装成真实运行。 证据：`README.md`, `package.json`, `CLAUDE.md`

## 用户开工前应该回答的问题

- 你准备在哪个宿主 AI 或本地环境中使用它？
- 你只是想先体验工作流，还是准备真实安装？
- 你最在意的是安装成本、输出质量、还是和现有规则的冲突？

## 验收标准

- 所有能力声明都能回指到 evidence_refs 中的文件路径。
- AI_CONTEXT_PACK.md 没有把预览包装成真实运行。
- 用户能在 3 分钟内看懂适合谁、能做什么、如何开始和风险边界。

---

## Doramagic Context Augmentation

下面内容用于强化 Repomix/AI Context Pack 主体。Human Manual 只提供阅读骨架；踩坑日志会被转成宿主 AI 必须遵守的工作约束。

## Human Manual 骨架

使用规则：这里只是项目阅读路线和显著性信号，不是事实权威。具体事实仍必须回到 repo evidence / Claim Graph。

宿主 AI 硬性规则：
- 不得把页标题、章节顺序、摘要或 importance 当作项目事实证据。
- 解释 Human Manual 骨架时，必须明确说它只是阅读路线/显著性信号。
- 能力、安装、兼容性、运行状态和风险判断必须引用 repo evidence、source path 或 Claim Graph。

- **Overview, Tech Stack and Deployment**：importance `high`
  - source_paths: README.md, package.json, Dockerfile, entrypoint.sh, docker-compose.yml
- **Extension System: Engines, Plugins, Themes, Transports and Store**：importance `high`
  - source_paths: src/server/extensions/registry-factory.ts, src/server/extensions/plugin-manifest.ts, src/server/extensions/engines/registry.ts, src/server/extensions/commands/registry.ts, src/server/extensions/transports/registry.ts
- **Settings UI, Search Pipeline and Indexer**：importance `high`
  - source_paths: src/server/utils/settings-schema.ts, src/server/routes/search.ts, src/server/routes/search/_search-routes.ts, src/server/routes/search/_search-handlers.ts, src/server/routes/search/_domain-rules.ts
- **Security, Localization, Shortcuts and Easter-Egg Features**：importance `medium`
  - source_paths: src/server/routes/settings-auth.ts, src/server/utils/settings-tokens.ts, src/server/utils/server-settings.ts, src/server/utils/public-instance.ts, src/server/utils/rate-limit.ts

## Repo Inspection Evidence / 源码检查证据

- repo_clone_verified: true
- repo_inspection_verified: true
- repo_commit: `d89504d322189081186faa4519a3b2ed358e36f0`
- inspected_files: `Dockerfile`, `README.md`, `docker-compose.yml`, `package.json`, `src/client/animations/lucky-animation.ts`, `src/client/animations/skeleton.ts`, `src/client/app.ts`, `src/client/constants.ts`, `src/client/modules/filters/image-filters.ts`, `src/client/modules/init.ts`, `src/client/modules/media/lightbox.ts`, `src/client/modules/media/media-preview.ts`, `src/client/modules/media/media.ts`, `src/client/modules/modals/confirm-modal/confirm.ts`, `src/client/modules/modals/docs-modal/docs.ts`, `src/client/modules/modals/prompt-modal/prompt.ts`, `src/client/modules/modals/settings-modal/list-field-data.ts`, `src/client/modules/modals/settings-modal/list-field.ts`, `src/client/modules/modals/settings-modal/modal-fields.ts`, `src/client/modules/modals/settings-modal/modal.ts`

宿主 AI 硬性规则：
- 没有 repo_clone_verified=true 时，不得声称已经读过源码。
- 没有 repo_inspection_verified=true 时，不得把 README/docs/package 文件判断写成事实。
- 没有 quick_start_verified=true 时，不得声称 Quick Start 已跑通。

## Doramagic Pitfall Constraints / 踩坑约束

这些规则来自 Doramagic 发现、验证或编译过程中的项目专属坑点。宿主 AI 必须把它们当作工作约束，而不是普通说明文字。

### Constraint 1: 来源证据：[Bug]: random image results

- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Bug]: random image results
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/degoog-org/degoog/issues/203 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 2: 依赖 Docker 环境

- Trigger: 安装/运行入口包含 Docker 命令：docker run -d --name degoog -p 4444:4444 -v ./data:/app/data -e DEGOOG_SETTINGS_PASSWORDS=changeme --restart unless-stopped ghcr.io/degoog-org/degoog:latest
- Host AI rule: 标注 Docker 前置条件，并提供非 Docker 路径或失败提示。
- Why it matters: 非工程用户可能没有 Docker，启动成本明显增加。
- Evidence: identity.distribution | https://github.com/degoog-org/degoog | docker run -d --name degoog -p 4444:4444 -v ./data:/app/data -e DEGOOG_SETTINGS_PASSWORDS=changeme --restart unless-stopped ghcr.io/degoog-org/degoog:latest
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 3: 来源证据：[Docs]: What is the Degoog engine?

- Trigger: GitHub 社区证据显示该项目存在一个安装相关的待验证问题：[Docs]: What is the Degoog engine?
- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/degoog-org/degoog/issues/173 | 来源讨论提到 docker 相关条件，需在安装/试用前复核。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 4: 可能修改宿主 AI 配置

- Trigger: 项目面向 Claude/Cursor/Codex/Gemini/OpenCode 等宿主，或安装命令涉及用户配置目录。
- Host AI rule: 列出会写入的配置文件、目录和卸载/回滚步骤。
- Why it matters: 安装可能改变本机 AI 工具行为，用户需要知道写入位置和回滚方法。
- Evidence: capability.host_targets | https://github.com/degoog-org/degoog | host_targets=mcp_host, claude, cursor
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 5: 能力判断依赖假设

- Trigger: README/documentation is current enough for a first validation pass.
- Host AI rule: 将假设转成下游验证清单。
- Why it matters: 假设不成立时，用户拿不到承诺的能力。
- Evidence: capability.assumptions | https://github.com/degoog-org/degoog | README/documentation is current enough for a first validation pass.
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 6: 来源证据：[Bug]: At-a-glance Plugins disappear once results fully load

- Trigger: GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：[Bug]: At-a-glance Plugins disappear once results fully load
- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/degoog-org/degoog/issues/175 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 7: 来源证据：[Bug]: Defaulting to wrong language

- Trigger: GitHub 社区证据显示该项目存在一个维护/版本相关的待验证问题：[Bug]: Defaulting to wrong language
- Host AI rule: 来源显示可能已有修复、规避或版本变化，说明书中必须标注适用版本。
- Why it matters: 可能增加新用户试用和生产接入成本。
- Evidence: community_evidence:github | https://github.com/degoog-org/degoog/issues/142 | 来源类型 github_issue 暴露的待验证使用条件。
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 8: 维护活跃度未知

- Trigger: 未记录 last_activity_observed。
- Host AI rule: 补 GitHub 最近 commit、release、issue/PR 响应信号。
- Why it matters: 新项目、停更项目和活跃项目会被混在一起，推荐信任度下降。
- Evidence: evidence.maintainer_signals | https://github.com/degoog-org/degoog | last_activity_observed missing
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

- Trigger: no_demo
- Evidence: downstream_validation.risk_items | https://github.com/degoog-org/degoog | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。

### Constraint 10: 存在评分风险

- Trigger: no_demo
- Why it matters: 风险会影响是否适合普通用户安装。
- Evidence: risks.scoring_risks | https://github.com/degoog-org/degoog | no_demo; severity=medium
- Hard boundary: 不要把这个坑点包装成已解决、已验证或可忽略，除非后续验证证据明确证明它已经关闭。
