Skip to content

Feature/1.0.0 - #1

Merged
ThreeFish-AI merged 71 commits into
masterfrom
feature/1.0.0
Feb 1, 2026
Merged

Feature/1.0.0#1
ThreeFish-AI merged 71 commits into
masterfrom
feature/1.0.0

Conversation

@ThreeFish-AI

Copy link
Copy Markdown
Owner

No description provided.

- 将项目简介扩展为完整的中文 README
- 新增 Getting Started 安装指南
- 新增 Repository Structure 说明
- 新增 Contributing 协作指引
- 新增 Getting Help 与 License 说明

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 定义 Core Language 与 Tone 规范
- 明确项目定位
- 制定工程行为准则(道、法、术)
- 规范文档标准(Mermaid可视化、IEEE引用)
- 建立知识索引框架

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 使用 GitHub 风格的 NOTE 块增强项目说明可读性
- 将前置要求章节标记为 WIP 状态
- 微调免责声明用词(演进→演化)

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 添加项目结构设计文档,包含目录组织与职责边界说明
- 新增 Mermaid 架构图与开发工作流可视化
- 补充常见陷阱、故障排查与验证检查清单
- 添加 IEEE 格式参考文献,符合循证工程原则

🤖 Generated with [Claude Code](https://github.com/claude)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 更新开发命令为 FastAPI 官方推荐的 uv run fastapi dev
- 补充 Next.js 官方启动指令说明
- 新增 IEEE 格式参考文献 [6]-[9]

🤖 Generated with [Claude Code](https://github.com/claude)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- Backend: Python + FastAPI + uv 项目结构
- Frontend: Next.js + TypeScript + Tailwind CSS 项目结构
- 配置各端 .gitignore 以排除依赖目录

🤖 Generated with [Claude Code](https://github.com/claude)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 新增 yarn create next-app 项目初始化命令

🤖 Generated with [Claude Code](https://github.com/claude)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 修正文档命名拼写(initiation → initialization)

🤖 Generated with [Claude Code](https://github.com/claude)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 新增 .python-version 指定 Python 3.14.2
- 将 main.py 移至 src/negentropy/ 目录,符合标准包结构
- 新增 src/negentropy/__init__.py 包初始化文件
- 降低 Python 版本要求至 >=3.13 以提升兼容性

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
新增 internalization 和 perception 两个代理模块,基于 Google ADK 框架和 LiteLLM 实现。

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 将 .adk/session.db 忽略规则从具体路径改为通配符模式
- 清理已提交的历史 session.db 文件

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 将 internalization 和 perception agent 的模型从 zai/glm-4.7 改为 openai/glm-4.7

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 将 agents 从子目录模式重构为扁平结构
- 新增根 agent.py 作为系统入口
- 新增 5 个职能 agent: perception, internalization, contemplation, action, influence
- 新增 tools 模块

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 将 root agent 从 src/negentropy/agent.py 移至 src/negentropy/agents/agent.py
- 将 5 个职能 agents 移至 src/negentropy/agents/faculties/ 子目录
- 将 tools 模块从 src/negentropy/tools/ 移至 src/negentropy/agents/tools/
- 更新 __init__.py 导出 root_agent

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 将 agent 名称从 NegentropyCore 更新为 NegentropyEngine
- 中文化 description 和 instruction
- 增强指令结构:核心哲学、五大系部正交分解、调度之道、约束
- 明确各系部的适用场景与目标

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 将 agent 名称后缀从 Agent 统一为 Faculty
- 中文化所有 description 和 instruction
- 增强指令结构:核心哲学、职责边界、运行协议、约束
- 明确各系部的定位:天眼(Perception)、本心(Internalization)、元神(Contemplation)、妙手(Action)、喉舌(Influence)

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 将 __init__.py 的导入方式恢复为 from . import agent
- 移除冗余的 agent 别名定义

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 新增 config.py 中央配置模块,支持环境变量 DEFAULT_MODEL
- 所有 agent 模型配置从硬编码改为 settings.default_model
- 统一导入路径为绝对路径 (from negentropy.xxx)
- 重构 main.py 导出 root_agent 供 ADK 使用
- pyproject.toml 新增 hatchling build 配置

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- pyproject.toml 新增 ruff linter 和 formatter 配置
- 新增 dependency-groups.dev 依赖 ruff
- 统一代码导入顺序和格式
- 调整 line-length 为 120,target-version 为 py313

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
新增 SQLAlchemy 异步数据库支持:
- 新增 db 模块 (base, session, deps)
- 配置类迁移至 Pydantic Settings
- 新增数据库连接池配置

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
新增:
- sqlalchemy[asyncio]>=2.0
- asyncpg>=0.31.0
- pydantic-settings>=2.12.0

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
配置类从 dataclass 迁移至 BaseSettings,支持环境变量加载,
新增数据库连接池相关配置项。

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
新增:
- pytest>=9.0.2
- pytest-asyncio>=1.3.0

配置 pytest 的 asyncio_mode 为 auto,自动处理异步测试函数。

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
新增统一的 ADK Runner 创建接口:
- get_runner(): 获取配置好的 Runner 实例
- reset_runner(): 重置单例缓存 (用于测试)
- 自动整合 SessionService 和 MemoryService
- 支持模块级单例缓存

遵循 Reuse-Driven 与 Orthogonal Decomposition 原则。

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
更新 engine/__init__.py 导出所有工厂函数:
- get_memory_service, reset_memory_service
- get_session_service, reset_session_service
- get_runner, reset_runner

提供统一的模块级 API 入口。

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
更新 main.py:
- 新增 runner 导出,使用 get_runner() 创建
- Runner 已配置 PostgreSQL 后端的 SessionService 和 MemoryService
- 打印配置信息用于调试

更新 agents 模块导入路径以适配目录重组。

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
清理数据库模块:
- 移除 db/base.py (Base 已移至 models/base.py)
- 移除 db/schema/ 目录 (SQL 文件移至 docs/schema/)
- 更新 db/__init__.py 移除 Base 导出
- 简化 db/deps.py 中的会话管理 (AsyncSessionLocal 已自动处理)

SQL Schema 文件现在归档在 docs/ 目录,保留为参考文档。
实际表结构以 Alembic 迁移脚本和 ORM 模型为准。

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
新增各系部专用工具函数:
- tools/action.py: 代码执行、文件操作
- tools/contemplation.py: 思维工具
- tools/influence.py: 内容生成工具
- tools/internalization.py: 记忆管理工具
- tools/perception.py: 信息获取工具

所有工具当前为占位实现,待后续与沙箱、存储等模块集成。

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
- 更新 agents/__init__.py 导出
- agent.py: 移除未使用的导入
- 各 faculty 模块: 简化代码结构

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
新增模型配置以支持分层架构:
- orchestrator_model: Root Agent 使用的强推理模型
- faculty_model: Faculty Agents 使用的通用模型

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
统一五大系部图腾命名:
- 感知: 天眼 → 慧眼
- 内化: 本心 (保持)
- 坐照: 元神 (保持)
- 知行: 妙手 (保持)
- 影响: 喉舌 (保持)

🤖 Generated with [Claude Code](https://github.com/claude), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
@ThreeFish-AI
ThreeFish-AI merged commit 4dde7c7 into master Feb 1, 2026
ThreeFish-AI added a commit that referenced this pull request Feb 25, 2026
ThreeFish-AI added a commit that referenced this pull request Apr 27, 2026
… × 502 上游错误码 × 诊断仪器化) (#421)

* fix(knowledge): 修复 Knowledge Base Retrieve 全屏空白(前端聚合 rejection + 后端 hybrid/rrf 降级 + 502 错误码 + 诊断日志);

双层 Bug 同因联修(详见 docs/issue.md ISSUE-026):
1. 前端 searchAcrossCorpora 旧实现以 Promise.allSettled 仅取 fulfilled,rejected 静默丢失,导致全部 Corpus 失败时返回 {count:0,items:[]} 走"成功路径"使 UI 空白且无任何提示——本次改为聚合三态(全成功/部分失败/全失败),SearchResults 类型扩展 errors[],handleRetrieve 对部分失败 toast.warning 透出原因;
2. 后端 service.search hybrid/rrf 旧实现未捕获 EmbeddingFailed,外部 Embedding 上游故障直接 500,丧失"keyword 仍可用"的优雅降级——本次 hybrid 失败回退 keyword-only、rrf 失败走与 not embedding_fn 等价的回退路径,semantic 仍传播以保留显式失败语义;
3. api.py _map_exception_to_http 拆分 EmbeddingFailed 分支映射到 502 Bad Gateway(保留 EMBEDDING_FAILED code),与 SearchError 自身错误的 500 区分,便于前端识别"上游修复后再试"语义;
4. embedding.py 调用 litellm 前后增加结构化诊断日志:api_base_host(脱敏 path/credentials 仅留 host)+ input_count + text_preview + kwargs_keys;失败附 upstream_response_text(沿异常链 __cause__/__context__ 提取 MaskedHTTPStatusError.text,已被 litellm 脱敏 URL,限长 500 字节);
5. 测试锁定:tests/unit_tests/knowledge/test_search_resilience.py 5 例(hybrid/rrf 降级 + semantic 传播 + EmbeddingFailed→502 + SearchError→500)+ tests/unit/knowledge/searchAcrossCorpora.test.ts 3 例(allSettled 三态);
6. docs/issue.md 追加 ISSUE-026,含后续防范(Promise.allSettled 必须聚合 rejection / vendor 失败必须 502 / hybrid 必须有降级路径 / vendor 调用必须 host+upstream_text 双信号)与同类问题影响清单。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(knowledge): searchAcrossCorpora 聚合保留 KnowledgeError code 并修正 _map_exception_to_http docstring;

Review #1(前端契约): SearchResultError 仅透 message 会丢弃 KnowledgeError.code(如 EMBEDDING_FAILED),削弱本次 502/500 拆分对前端"上游修复 vs 自身错误"的可分流价值——本次扩展 SearchResultError 增加可选 code,rejection instanceof KnowledgeError 时回填;全失败分支由 throw new Error 改为 throw new KnowledgeError(aggregatedCode, msg, {errors}),code 一致时透传原 code、混合时退化为 AGGREGATED_SEARCH_ERRORS,既保留分流能力又携带逐条失败明细;新增 1 例同 code 透传 + 1 例混合 code 退化的单测,全部 4 例通过。

Review #2(后端文档): api._map_exception_to_http docstring 仍只列 400/404/409/500,与新增 EmbeddingFailed→502 分支不一致;本次补 "502: 上游服务错误(vendor / Embedding 等外部依赖)" 一行,避免后续维护者按旧映射加分支。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
ThreeFish-AI added a commit that referenced this pull request May 5, 2026
…at 双气泡终结 + YAML 配置统一 (#462)

* feat(agent-defs): 主 Agent 入库 + 按 DB 读 instruction + 模型选择回退 (#420)

* fix(agent-defs): 修复 Agent 加载路径 + 主 Agent 纳入 Interface Sync + 运行时按 DB 读 instruction;

- cli.py: --reload_agents 改用 Path(__file__) 推导的绝对路径,杜绝 cwd 依赖导致的「src/negentropy/negentropy」双重段错误;
- subagent_presets: 新增 NegentropyEngine root payload(adk_config.kind="root"),Sync 后 DB 出现主 Agent 行;
- sync API: 循环写入 config.kind,末尾调 invalidate_cache(prefix="subagent:") 批量失效;
- SubAgentResponse: 新增顶层 kind 字段(root/subagent),供前端置顶 + 徽章;
- model_resolver: 抽取 _load_subagent_row 共用单行查询,新增 resolve_subagent_instruction;
- _dynamic_instruction: 新增 InstructionProvider 工厂,root + 5 子 Agent 的 instruction 接入运行时 DB 读取;
- 测试: 更新 test_subagent_presets 覆盖 root payload + kind 断言;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-llm): 修复无 Session 时模型选择回退 + SubAgents 列表 Root 置顶徽章;

- home-body: 新增 pendingLlmRef,改写 handleSelectedLlmModelChange 与 Effect 1,
  使「无 session 选模型→建 session→自动发送」全流程保持选择不丢失;
- SubAgents page: 按 kind="root" 置顶排序,Sync 按钮文案从「Sync Negentropy 5」改为「Sync Negentropy」;
- SubAgentCard: Root Agent 显示 violet 色 Root 徽章;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(model-resolver): SubAgent 行缺失/未启用补回 60s TTL 负命中缓存;

回归点:重构 `_resolve_subagent_row` 时把空占位写入移到了 `loaded is None`
判断之后,导致禁用 Faculty 与未 Sync 环境下每次 LLM 请求都触发一次 DB 查询。
本次在 `loaded is None` 分支补 `_cache[cache_key] = ("", {"i": ""}, now)`,
让负命中同样落入 60s TTL,避免重复 DB 压力。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-llm): pending 模型选择仅对 startNewSession 新 id 消费;

回归点:Effect 1 的 pending 转移分支会在「首次进入既有 session」时触发,
把无 session 阶段的 pending 模型写入该 session 的 perThreadLlmRef,
并让 Effect 2 跳过 snapshot 初始化,导致服务器端记忆模型被静默替换。

修复方式:
- 新增 `pendingLlmTargetIdRef` 仅记录 startNewSession 返回的新 id;
- 通过 `startNewSessionWithLlmTarget` 包装内联调用与 `onNewSession` 两条路径;
- Effect 1 仅在 `sessionId === pendingLlmTargetIdRef.current` 时转移 pending,
  其余进入既有 session 的分支主动丢弃 pending,让 snapshot 正常生效。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(knowledge): 修复 KB Retrieve 全屏空白(前端聚合 rejection × 后端 hybrid/rrf 降级 × 502 上游错误码 × 诊断仪器化) (#421)

* fix(knowledge): 修复 Knowledge Base Retrieve 全屏空白(前端聚合 rejection + 后端 hybrid/rrf 降级 + 502 错误码 + 诊断日志);

双层 Bug 同因联修(详见 docs/issue.md ISSUE-026):
1. 前端 searchAcrossCorpora 旧实现以 Promise.allSettled 仅取 fulfilled,rejected 静默丢失,导致全部 Corpus 失败时返回 {count:0,items:[]} 走"成功路径"使 UI 空白且无任何提示——本次改为聚合三态(全成功/部分失败/全失败),SearchResults 类型扩展 errors[],handleRetrieve 对部分失败 toast.warning 透出原因;
2. 后端 service.search hybrid/rrf 旧实现未捕获 EmbeddingFailed,外部 Embedding 上游故障直接 500,丧失"keyword 仍可用"的优雅降级——本次 hybrid 失败回退 keyword-only、rrf 失败走与 not embedding_fn 等价的回退路径,semantic 仍传播以保留显式失败语义;
3. api.py _map_exception_to_http 拆分 EmbeddingFailed 分支映射到 502 Bad Gateway(保留 EMBEDDING_FAILED code),与 SearchError 自身错误的 500 区分,便于前端识别"上游修复后再试"语义;
4. embedding.py 调用 litellm 前后增加结构化诊断日志:api_base_host(脱敏 path/credentials 仅留 host)+ input_count + text_preview + kwargs_keys;失败附 upstream_response_text(沿异常链 __cause__/__context__ 提取 MaskedHTTPStatusError.text,已被 litellm 脱敏 URL,限长 500 字节);
5. 测试锁定:tests/unit_tests/knowledge/test_search_resilience.py 5 例(hybrid/rrf 降级 + semantic 传播 + EmbeddingFailed→502 + SearchError→500)+ tests/unit/knowledge/searchAcrossCorpora.test.ts 3 例(allSettled 三态);
6. docs/issue.md 追加 ISSUE-026,含后续防范(Promise.allSettled 必须聚合 rejection / vendor 失败必须 502 / hybrid 必须有降级路径 / vendor 调用必须 host+upstream_text 双信号)与同类问题影响清单。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(knowledge): searchAcrossCorpora 聚合保留 KnowledgeError code 并修正 _map_exception_to_http docstring;

Review #1(前端契约): SearchResultError 仅透 message 会丢弃 KnowledgeError.code(如 EMBEDDING_FAILED),削弱本次 502/500 拆分对前端"上游修复 vs 自身错误"的可分流价值——本次扩展 SearchResultError 增加可选 code,rejection instanceof KnowledgeError 时回填;全失败分支由 throw new Error 改为 throw new KnowledgeError(aggregatedCode, msg, {errors}),code 一致时透传原 code、混合时退化为 AGGREGATED_SEARCH_ERRORS,既保留分流能力又携带逐条失败明细;新增 1 例同 code 透传 + 1 例混合 code 退化的单测,全部 4 例通过。

Review #2(后端文档): api._map_exception_to_http docstring 仍只列 400/404/409/500,与新增 EmbeddingFailed→502 分支不一致;本次补 "502: 上游服务错误(vendor / Embedding 等外部依赖)" 一行,避免后续维护者按旧映射加分支。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(wiki-favicon): 修复 negentropy-wiki 站点 favicon.ico 单分辨率畸形导致浏览器回落默认地球图标; (#423)

- 根因:apps/negentropy-wiki/src/app/favicon.ico 是单分辨率畸形 ICO(file 输出 256x-1,高度字节 0xFF),且源图 logo.png 为非方形 800x798,导致 Chrome/Firefox/Safari 解析失败、tab 回落默认地球图标;
- 修复:用 Pillow 对 logo.png 做透明 padding 至 800x800 方形,再生成多分辨率 ICO(16/32/48/64/128/256 共六档)覆盖原文件;体积从 269KB 降至 118KB;
- 验证:file 输出 6 icons; pnpm build 后 .next/standalone 内 favicon route + body + meta 完整;pnpm start 后 curl /favicon.ico 返回 200 image/x-icon,HTML 自动注入 <link rel="icon">;
- 防范:docs/issue.md 追加 ISSUE-027,沉淀「ICO 必须方形 + 多分辨率」工程约束与 Pillow 流水线模板,禁止「原图直裹 ICO 头」反模式;
- 不动:layout.tsx / next.config.ts / start-production.mjs,保留 App Router metadata 自动注入路径,最小干预。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* feat(mcp-resources): 接入 Resource Templates 并贯通 PDF 图片到 Wiki Markdown (#422)

* feat(mcp-client): 接入 MCP Resource Templates 与同会话动态资源拉取;

新增 McpResourceTemplate 模型与 Alembic migration 0012,扩展 McpClientService 在
连接发现阶段并发调用 list_resource_templates(旧 server 不支持时静默兜底,不
阻断 tools 发现),新增 call_tool_and_resolve_resources:在同一 ClientSession 内
完成工具调用与所有 resource_link URI 的并发拉取(Semaphore 限流 4,return_exceptions
保证单条失败不击穿主流程)。这是接入 Negentropy Perceives 动态 FileResource
(perceives://pdf/<job_id>/<filename>)的协议层基石——动态实例的生命周期与工具
会话强绑定,必须在 session 关闭前完成 resources/read 才能避免事后失链。

Interface API 同步:load_mcp_server_tools 端点扩展为 capability 全量同步(tools
+ resource_templates,软删除已下线的 templates),LoadToolsResponse 新增
resource_templates 字段(向后兼容),新增 GET /mcp/servers/{id}/resource-templates
端点;list_mcp_servers 拆解为分段计数避免 JOIN 笛卡尔积;McpServerResponse 暴露
resource_template_count 给前端展示。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(perceives-resources): PDF 图片资源端到端贯通到 GCS 与 Wiki Markdown;

把 Perceives MCP 工具调用返回的 ResourceLink 接入既有提取流水线(Ingest 与
Re-Parse from GCS),让 PDF 图片资源在主仓 ↔ Perceives 之间通过 MCP 协议
完整贯通:

- 提取层(extraction.py):新增 _extract_resource_link_assets 把 ResourceLink
  与同会话 read_resource 拉取的 base64 配对为 ExtractionAsset;_call_tool_with_plan
  改用 resolve_resource_links=True 路径,确保动态 URI 不会因会话关闭失链;
  _build_success_result 接收 resolved_resources / resource_errors,按 "warn +
  占位" 容错策略合并 assets 并标记 partial_failure 不阻断主入库;新增
  _rewrite_markdown_image_links 在 Markdown 写入 GCS 之前把相对路径图片引用
  重写为 /api/documents/{doc_id}/assets/{filename},重写采用 capture group 偏移
  以避免 alt 文本含同名 src 时误替换。

- Knowledge API:新增 GET /knowledge/wiki/documents/{document_id}/assets/{filename}
  公开端点,filename 严格白名单 ^[A-Za-z0-9._-]+$ 与 180 字符上限;鉴权策略与
  既有 wiki entry content 端点对齐——仅放通至少被一条 WikiPublicationEntry
  引用的 document,避免持任意 doc_id 拖走未发布文档资产。

- 前端 MCP 卡片(negentropy-ui):新增 Resource Templates 折叠区与 ResourceDetailPanel,
  视觉与 Tools 区完全镜像;page.tsx 在 tools:load 响应中同步消费
  resource_templates 段,状态合并到 ServerWithTools;动态实例(带 job_id)
  按设计不入卡片。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(mcp-client): Resource Templates 同步加 capability flag,避免静默兜底误清空模板表;

`_discover_on_transport` 对 `list_resource_templates` 的所有异常都会静默兜底返回空列表(兼容旧 server 与瞬态错误),但 `load_mcp_server_tools` 会把空列表当作权威结果裁剪 stale 行,导致一次网络抖动或 server bug 即抹掉全部模板;同时与 tools 同步"只增量更新、不裁剪"的语义不对称。

- `McpConnectionResult` 新增 `resource_templates_listed: bool`,仅在 `list_resource_templates` 成功返回时为 True;
- `load_mcp_server_tools` 仅在该 flag 为 True(权威空列表)时才裁剪 stale 模板,未支持/错误场景保留既有 DB 行;
- 单元测试覆盖 flag 在权威空列表与异常兜底两种路径下的取值。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(mcp-card): 单测 server fixture 补 resource_template_count 修 UI Type Checks;

`McpServer` 类型新增的必填字段 `resource_template_count` 未同步到 `McpServerCard.test.tsx` 的 server 固件,导致 ui-quality / UI Type Checks 在 5 处 `<McpServerCard server={...}>` 调用上报 TS2741。

- 在 server 固件加 `resource_template_count: 0`,spread 派生用例自动获得新字段。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(knowledge): 查询时 honor Corpus 自配 embedding 模型,修复 query/index 模型不一致 (ISSUE-028) (#424)

search() 原直接使用实例化时锁定的 self._embedding_fn(全局默认 gemini/text-embedding-004),
未读 corpus.config.models.embedding_config_id;而 _attach_embeddings 索引侧已按 corpus pin 走
专属 fn。两侧不对称导致:用户在 Corpus Settings 已切到 openai/text-embedding-3-small(1536 维),
索引按 OpenAI 生成,查询仍走 Gemini 全局默认经 localhost:3392 翻译代理报 400。

修复:
- 新增 _resolve_embedding_fn(corpus_config) 助手,corpus pin 优先 → 退回 service 默认 fn;
- search() 入口加载 corpus_config + embedding_fn 本地变量,rrf/hybrid/semantic 三分支替换;
- ISSUE-026 keyword 兜底 + 502 映射 + 诊断日志原样保留,零回归;
- 新增 5 例单元测试覆盖 corpus pin 命中/落空/兜底/rrf/semantic 上抛,577 全绿。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* fix(agent-llm): 修复 Home Send 时 LLM 凭证未从 DB 读取导致 AuthenticationError (#425)

* fix(docs): 同步文档启动命令与 cli.py 修复,消除 Home Send 500 复发路径;

cli.py 的 agents_dir 已在 35204ff 从 src/negentropy 修正为 src,
但 README / docs 下 4 个文件 7 处仍写 --reload_agents src/negentropy,
用户照文档启动复现 ValueError: Agent not found 500。
统一替换为 uv run negentropy serve(SSOT),
追加 ISSUE-029(文档漂移)与 ISSUE-030(SubAgents root Agent 防回归)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(agent-llm): 修复 Home Send 时 LLM 凭证未从 DB 读取导致 AuthenticationError;

DynamicRootLiteLlm/DynamicSubagentLiteLlm 在 ContextVar 或 sub_agents.model
为空时直接返回 None,回退到构造时无 api_key 的硬编码实例,绕过了 DB 中
已配置的 vendor_configs 凭证。现在始终通过 resolve_llm_config() 从 DB
解析默认模型的完整凭证(含 api_key)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复长耗时回复双气泡 + 首条未格式化 (ISSUE-031); (#426)

ADK 仅持久化 partial=false 终态事件,realtime 与 hydration 在
同一逻辑消息上派出不同的 messageId(首个 partial id vs 终态 id)。
isSemanticEquivalentEntry 的 8s 时间窗在长耗时回复下硬拒绝,导致
ledger 双 entry → events 过滤失败 → conversation tree 双节点 →
UI 渲染双气泡(首条因 streaming-markdown 尾部判定走 raw text 分支)。

修复 (最小干预 + 正交分解):
- message-ledger.ts: 内容严格相等时跳过 8s 时间窗硬拒绝。
- conversation-tree.ts: assistant 已收尾节点在内容严格相等时
  也允许 findMatchingTextNodeId 命中复用,作为防御性收敛。
- 三层回归测试覆盖 ">8s 跨度 + messageId 不同 + 内容严格相等"。

UI 全量 70 文件 396 测试通过;typecheck/typecheck:test/eslint 零报错。
docs/issue.md 沉淀 ISSUE-031;CHANGELOG.md 同步条目。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* fix(home-chat): 修复 Home 对话 title 凭证缺失与 OTLP logs/metrics 404 双联缺陷 (#427)

* fix(home-chat): 修复 Home 对话 title 凭证缺失 + OTLP logs/metrics 404 双联缺陷;

(1) SessionSummarizer 同步 __init__ 在 60s 缓存 miss 时回退到无 api_key 硬编码默认,
导致 LiteLLM AuthenticationError;改为 async classmethod create() 经 resolve_llm_config()
从 DB 读取完整凭证(与 commit 8ce35d5 修复 DynamicRootLiteLlm 同 SoT),调用方
session_service._generate_title_for_session 切换为 await SessionSummarizer.create(),
对 resolver 返回 kwargs 做防御性浅拷贝避免与 60s 缓存层耦合。

(2) ADK 上游 _get_otel_exporters() 把 OTEL_EXPORTER_OTLP_ENDPOINT 视为 OTLP 三件套
总开关,无差别注册 OTLPSpanExporter / OTLPMetricExporter / OTLPLogExporter;后两者
对 Langfuse 不存在的 /v1/metrics、/v1/logs 上报触发 SPA 404 SSR 错误页(每次对话
反复输出大段 HTML)。bootstrap.py 新增 _install_noop_otel_logs_metrics_providers()
在 OTel env var 设置后立即抢注无 processor / 无 reader 的 SDK Logger/Meter Provider,
利用 OTel SDK Once-lock 让 ADK 后续 set_*_provider 静默 no-op,从而阻断 logs/metrics
上报;TracerProvider 链路与 OTEL_EXPORTER_OTLP_HEADERS 不动,traces 仍正常进入 Langfuse。

新增 tests/unit_tests/engine/test_summarization.py(3 例)+
tests/unit_tests/observability/test_otel_noop_providers.py(3 例,子进程隔离 OTel 全局
状态)锁定回归。CHANGELOG / docs/issue.md 沉淀 ISSUE-031(title 凭证缺失)与
ISSUE-032(OTLP logs/metrics 404)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(otel-noop): 移除 _sdk_config hasattr 兜底,让 SDK 私有属性变更显式触发回归;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(session-title): 修复 DummySummarizer 缺失 async create() 导致集成测试 AttributeError;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(bootstrap-otel): 消除 ADK Web 启动期 OTel Override Provider 双 WARNING (ISSUE-034); (#428)

将 ISSUE-033 的「抢占式 set_logger_provider/set_meter_provider」改为 patch
`google.adk.telemetry.setup._get_otel_exporters`,让其只返回 traces 的
span_processors,metric_readers/log_record_processors 永久置空。ADK
maybe_set_otel_providers 的 if 分支由此天然短路,set_*_provider 根本不被
调用,从源头消除 OTel SDK 的 "Overriding of current ... is not allowed"
WARNING;traces 链路、ADK ApiServerSpanExporter、TracingManager、LiteLLM
"otel" callback 行为完全不变。配套更新 3 个子进程隔离单测验证新语义,
并在 docs/issue.md 追加 ISSUE-034 完整记录。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* feat(e2e-auth): 浏览器验证协议落地 + Playwright 会话复用贯通 Google OAuth (#429)

* docs(browser-validation): 落地浏览器验证协议并补 ISSUE-034

- AGENTS.md(即 CLAUDE.md symlink)新增"Browser Validation Protocol"子节,
  约定登录态浏览器验证必须复用用户常用 Chrome 会话,禁止 sandbox 浏览器
  通过 Google 同意屏,明确凭证守则与三步连通性自检;
- 新建 docs/agents/browser-validation.md:含三种 MCP 浏览器工具能力对照、
  Mermaid 选型决策图、storageState 工作时序、风控应对、IEEE 引用;
  实测附注 chrome-devtools MCP 在 macOS 默认即可复用用户主 profile 登录态;
- docs/issue.md 追加 ISSUE-034,记录 sandbox 浏览器走 Google OAuth 被拦
  的表因/根因/处理方式/防范,便于跨上下文复用。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(e2e-auth): Playwright 会话复用以贯通 Google OAuth E2E

- playwright.config.ts 在 PLAYWRIGHT_AUTH=1 时启用两个项目:
  * setup(headless: false,匹配 *.setup.ts),让用户在弹出窗手动登录;
  * chromium-authenticated(dependencies: ['setup']),使用 storageState
    复用一次性人工登录的会话;
  支持 PLAYWRIGHT_STORAGE_STATE 与 PLAYWRIGHT_USER_DATA_DIR 覆盖默认;
  现有 chromium project 加 testIgnore 排除 .setup.ts,CI/默认行为零变;
- 新增 tests/e2e/auth.setup.ts:打开 /auth/google/login,5 分钟内允许
  用户在 Google 同意屏中手动完成登录,回跳后断言 /api/auth/me 2xx,
  写入 storageState;
- .gitignore 追加 apps/negentropy-ui/.auth/ 与 .userdata/,
  防止会话凭证随分支推送外泄。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(e2e-auth): 修复 OAuth setup 早退与 authed spec 双跑;

- auth.setup.ts: waitForURL 谓词追加 host 约束,避免在跳往 accounts.google.com
  瞬间因 pathname 已离开 /auth/google 而误判完成,导致 /api/auth/me 在用户登录前
  失败、storageState 永不写出。
- playwright.config.ts: 基础 chromium project 的 testIgnore 追加
  /.*\.authed\.spec\.ts$/,防止 PLAYWRIGHT_AUTH=1 时同一份认证 spec 在
  chromium-authenticated 与 chromium 中各跑一次(后者无 storageState 必失败)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复 Home 双气泡复发与 LLM 模型未 Send 即刷新丢失 (ISSUE-032/033); (#430)

ISSUE-032 (双气泡复发,与 ISSUE-031 正交):
- 根因:root agent prompt 主动导航 + log_activity tool 让 ADK 走双轮 LLM 调用,
  两轮各自带独立 messageId 走完整 TEXT_MESSAGE_* 三件套,UI 在同一
  assistant-reply bubble 内并列渲染两段近重复文本。
- 修复:utils/chat-display.ts::dedupeRedundantTextSegments 在
  buildAssistantReplyBlock 出口对同一 reply 内的 text segment 做字符二元组
  Jaccard 相似度计算,相似度 ≥ 0.5 且双方长度 ≥ 30 时丢弃前段、保留信息更
  完备的最终段。tool-group / reasoning / error 顺序不动。
- assistant-reply.message.content 联动重组,复制时也拿到折叠后的内容。

ISSUE-033 (LLM 模型未 Send 即刷新丢失):
- 根因:后端事实源 session.state.selected_llm_model 仅在 /run_sse 时随
  state_delta 写入,未 Send 时不更新;前端 perThreadLlmRef 是 useRef
  刷新即丢;snapshotForDisplay 也无值,回退到 default。
- 修复:app/home-body.tsx 顶部新增 readPersistedLlmModel /
  writePersistedLlmModel (typeof window 守卫 + try/catch SSR 安全);
  handleSelectedLlmModelChange 即时落盘到 localStorage;Effect 1 优先
  从 localStorage 还原;Effect 2 命中 snapshot 时同步回写 localStorage,
  让「后端 state ↔ localStorage」互为镜像。既有 forwardedProps.selected_llm_model
  在 Send 时仍写后端 state,跨设备一致性最终收敛。

测试:
- 新增 2 例 chat-display.test.ts 用例:折叠近重复段 + 差异度大不被折叠
- UI 全量 70 文件 398 测试通过;typecheck/typecheck:test/eslint 零报错

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* fix(bootstrap-otel): 消除被丢弃 PeriodicExportingMetricReader 守护线程的周期 WARNING (ISSUE-038) (#431)

* fix(bootstrap-otel): 消除被丢弃 PeriodicExportingMetricReader 守护线程的周期 WARNING (ISSUE-038);

ISSUE-034 的 patch 调用 original() 后再丢弃 metric_readers /
log_record_processors,但上游 _get_otel_exporters 已构造
PeriodicExportingMetricReader 并启动 60s 守护线程——reader 未注册
到 MeterProvider 导致每 tick 触发 "Cannot call collect on a
MetricReader ..." WARNING。改为绕过 original(),直接复用
_get_otel_span_exporter() 仅构造 traces span processor,根源
避免 OTLP metrics/logs exporter 被实例化。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(bootstrap-otel): 修正 _disable_adk_otel_logs_metrics_exporters docstring 中的过期 hooks 引用;

旧 docstring 沿用重构前 `hooks = original()` 的中间变量术语,但新实现已不再调用 `original()`,函数体内也没有 `hooks` 绑定。
更新指引为「恢复 _get_otel_exporters 原函数闭包」或「直接构造完整 OTelHooks」,避免误导后续维护者寻找已不存在的对象。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复 Home 双气泡盲区与刷新后消息乱序 (ISSUE-039) (#432)

* fix(home-chat): 修复 Home 双气泡盲区与刷新后消息乱序 (ISSUE-038);

- chat-display: dedupeRedundantTextSegments 增加四层判定(精确匹配 / 严格前缀 / 等价内容 / Jaccard),覆盖 ADK 双轮 LLM 短回复(如 "Pong!")的双气泡盲区。
- session-hydration: mergeEventsWithRealtimePriority 交换参数顺序,让 realtime 事件覆盖 hydrated;TEXT_MESSAGE_CONTENT 的 eventKey 时间戳改用 toFixed(3) 消除浮点抖动导致的同一事件重复保留。
- message-ledger: MessageLedgerEntry 新增可选 sourceOrder 作 createdAt 相同时的稳定 tiebreaker,替代 UUID localeCompare 的随机字典序;抽出 compareLedgerEntriesByTime 复用,类型保持向后兼容(缺省回退 Number.MAX_SAFE_INTEGER)。
- 新增 5 项单元测试覆盖:短回复精确匹配、前缀含尾部追加、Jaccard 长文本、eventKey 浮点稳定、sourceOrder 稳定排序;docs/issue.md 增补 ISSUE-038 摘要。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(home-chat): 补 mergeEventsWithRealtimePriority 生命周期事件覆盖回归用例;

针对 ISSUE-039 第 3 项修复(mergeEventsWithRealtimePriority 参数顺序交换)
原有 RUN_STARTED 类生命周期事件用例缺位——之前的 messageId 重叠用例在
step 3 即被过滤为 filteredHydratedEvents=[],无法验证 step 4 mergeEvents
入参顺序对 key 冲突归并的影响。

补一条 RUN_STARTED 用例:realtime / hydrated 同 threadId/runId/timestamp
(eventKey 字节级一致)→ 用对象引用断言保留的是 realtime 版本,作为参数
顺序交换的最直接证据。该用例在交换前会失败、交换后通过,形成有效回归网。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 消除 LLM 思考独白溢出 / 推理头常驻 / 刷新乱序残留 (ISSUE-040) (#433)

* fix(home-chat): 消除 LLM 思考独白溢出 / 推理头常驻 / 刷新乱序残留 (ISSUE-040);

- 过滤 ADK Part 中 thought=true 与 type=thinking|thought|reasoning 系列推理字段,避免 reasoning_content 溢出到 TEXT_MESSAGE_CONTENT;推理文本改路由为 ne.a2ui.thought 自定义事件保留可观测性。
- createStepFinishedEvent 同步透出 stepName,AdkMessageStreamNormalizer 持有 stepId→stepName 映射,根治 ag-ui v0.0.47 校验器 "Cannot send 'STEP_FINISHED' for step \"undefined\"" 中断 run 导致的推理头永驻 started 现象。
- conversation-tree fallback 段重建消息节点时优先复用 ledger 已有 sourceOrder,避免被推到 events 末尾破坏 compareLedgerEntriesByTime tiebreaker。
- session-hydration eventKey 全事件类型统一走 toFixed(3) 毫秒级时间戳,并为 STEP_STARTED/STEP_FINISHED 显式按 (threadId, runId, stepId) 作 key,覆盖 STEP_*/CUSTOM/STATE_*/RAW 在浮点抖动下的去重盲区。
- 新增 9 例单元回归覆盖 thought part 过滤 / STEP_FINISHED stepName / fallback sourceOrder / eventKey 浮点抖动;docs/issue.md 追加 ISSUE-040 全栈解析。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 消除 hydration sort 字典序污染 lifecycle 顺序导致的多消息刷新乱序 (ISSUE-040 Q3 长尾);

- hydrateSessionDetail 引入 WeakMap<BaseEvent, emitOrder>,sort tiebreaker 用 normalizer 推入顺序代替 eventKey().localeCompare,保留 TEXT_MESSAGE_* 三件套 START→CONTENT→END 与跨 messageId 的 turn 边界。
- mergeEvents 同步改为按首次出现位置记录 insertionOrder 作 tiebreaker,避免最后一步 mergeEvents([], normalizedEvents) 再把刚排好的事件按字典序乱序。
- 新增同 timestamp 下 lifecycle 顺序断言用例;多轮真实后端 events fixture 经修复链路输出 user(R1)→assistant(R1)→user(R2)→assistant(R2) 完全符合时间线。
- docs/issue.md 在 ISSUE-040 末尾追加 Q3 长尾闭环(H5 字典序污染根因与最小干预修复)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(home-chat): 强化 ISSUE-040 H3 fallback sourceOrder 回归用例;

- 旧用例与单 snapshot 单条消息时新旧公式恰巧同值,断言无差异,无法拦截 H3 退化;
- 新用例构造「snapshot 数组顺序 vs ledger 时间序」错位场景:让 sourceOrder 在两条消息间发生互换,对回滚 H3 修复有强差异断言(已本地反向核验:回滚 conversation-tree.ts 修复后断言失败)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(wiki-header): catalog 第一层提升为顶部 Header 导航 tabs (#434)

* feat(wiki-header): catalog 第一层提升为顶部 Header 导航 tabs;

将 publication catalog 的第一层 CONTAINER 节点(如 Harness-Engineering)
从左侧 Sidebar 迁移为顶部 Header tabs;第二层及以下保留于 Sidebar,整树向上提升一档。
设计参考 GitHub Docs / Stripe Docs / Docusaurus 的"顶 tabs + 左 sidebar 子树"模式。

主要变更:
- lib/wiki-api.ts 追加 findFirstDocumentSlug / findActiveTopLevelSlug / resolveSectionView
  纯函数,作为 Header tabs 与 Sidebar 切片的单一事实源。
- 新增 WikiHeader Server Component(仅 <Link>,SSG 友好):渲染品牌 + 水平 tabs;
  CONTAINER tab 跳转 DFS 首个后代 DOCUMENT;无文档则禁用 span。
- WikiLayoutShell 增加 header? prop,渲染于 .wiki-layout 之外作为兄弟节点,
  避免触动既有 3 列 Grid 与 data-toc 三态。
- /{pubSlug} 与 /{pubSlug}/{...entrySlug} 两条路由共用 resolveSectionView 派生视图:
  pub 根页默认激活首项;entry 页按 slug 反查所属一级。
- globals.css 引入 --wiki-header-height 并把 sidebar / toc-aside 的 sticky top
  改为 var 引用,确保滚动时 Header 常驻不挡 sidebar。
- 新增 wiki-section-view.test.ts 12 用例覆盖空树 / 单 / 多 / 深路径 / DOCUMENT-only
  / 无后代 DOCUMENT 等边界。

回归保障:home / 不变;既有 WikiNavTree / WikiToc 测试 API 未变;47/47 单测全绿。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(wiki-header): Header 缺失时 sidebar/toc 不再残留偏移;

通过 data-header 属性标记 Header 是否存在,CSS 侧条件生效
--wiki-header-height 偏移,避免空导航树时出现 56px 空白间隙。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* refactor(config): 废弃 .env*,统一 YAML 三级配置(local > user > default) (#436)

* refactor(config): 废弃 .env* 加载链路,引入 config.local.yaml 统一 YAML 三级配置;

- 移除 10 个 Python 配置模块中的 env_file / _get_env_files 逻辑
- yaml_loader 新增 config.local.yaml 作为最高优先级 YAML 来源
- config.default.yaml 合并 .env 全部非机密差异值(含 OAuth 端口 6600→3292 校正)
- 新增 3 例 config.local.yaml 优先级测试

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(config): 同步 .env 废弃后的文档与 CHANGELOG;

- development.md / sso.md / framework.md / user-guide.md / zh-CN/README.md 中 .env 引用替换为 config.local.yaml
- CHANGELOG 新增 ISSUE-041 变更记录
- docs/issue.md 新增 ISSUE-041 经验沉淀
- .gitignore 新增 apps/negentropy/config.local.yaml 排除规则

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(config): 放宽 .gitignore 中 config.local.yaml 匹配规则,覆盖任意 cwd 场景;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041) (#435)

* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041);

- 新增 isSyntheticRunId 共享识别函数(覆盖 runId 缺失 / DEFAULT_RUN_ID / runId === threadId 三类合成回退标记),三层 dedup 一致放宽:
  1. message-ledger.ts::isSemanticEquivalentEntry:runId 不等时若任一侧 synthetic 则放行,threadId + role + 内容前缀 + origin 多元仍是必要约束;
  2. conversation-tree.ts fallback 段 runMatches:识别合成 runId 兼容分支,避免同内容 fallback message 被强制重建为重复节点;
  3. conversation-tree.ts collapseDefaultTurnDuplicates → collapseSyntheticTurnDuplicates:扩展为识别 runId === threadId 的合成 turn;时间窗判定改为 per-child timestamp vs concrete turn timeRange,多轮场景下不再误放过期 concrete turn。
- session-hydration.ts::fallbackRunId 注释 ISSUE-041 契约(保留兜底防御,等 Phase 2 后端代理层注入 runId 后再渐进移除)。
- 新增 16 例自动化回归(含 1 例反向回滚断言):
  · message-ledger A1-A5 + isSyntheticRunId 单元 + 端到端 ledger merge(共 7 例);
  · conversation-tree C1/C2/C3/C5 + D4 反向回滚(共 5 例);
  · session-hydration D1/D1+/D2/D3 端到端(共 4 例)。
- docs/issue.md 追加 ISSUE-041 全栈解析(含 refresh 自愈非对称的根因证据、多轮二阶恶化、Phase 2-4 路线图、诊断抓手与同类问题影响),闭环 ISSUE-040 Q3 长尾自识别。

回归状态:482 测试全绿 + tsc 0 错误;浏览器实机 5 场景 × 3 次验证清单见 .context/issue-041/validation-protocol.md,待用户已登录态 Chrome 桥接就绪后执行。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(rfcs): 新增 Phase 3 / Phase 4 架构 RFC 草稿(ISSUE-041 后续路线图);

- docs/rfcs/0001-conversation-architecture-refactor.md:Phase 3 架构重塑 RFC(Codex Thread→Turn→Item 数据模型 / 6 层去重金字塔精简到 3 层 / 抽象 utils/dedup/ + config/projection-thresholds.ts / 投影缓存 / 8 sub-PR 渐进迁移路线 / 兼容性回归与风险评估)。
- docs/rfcs/0002-ui-interaction-enhancements.md:Phase 4 UI 交互能力 backlog(Reasoning Panel + Sub-Agent 嵌套 / 工具进度 + 中断审批 / Conversation Branching + Timeline 增强;按用户优先级 1/2/3 分组,附实施依赖图与 Acceptance Criteria)。

均为 Draft 状态,待团队评审通过后启动多 PR 渐进迁移。本 commit 仅文档先行,不动代码。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 增强 synthetic turn 折叠相似度判定与时间窗整体吸收 (ISSUE-041);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 双层防御消除跨 runId 三气泡——泛化 turn 折叠 + 跨 block 去重 (ISSUE-041);

将 collapseSyntheticTurnDuplicates 泛化为 collapseOverlappingTurns:按 threadId 分组,
对 synthetic turn 与同组 concrete turn 时间重叠+内容覆盖的进行折叠(双 concrete turn
保留以防误折叠合法多 run);新增 chat-display 层 dedupeAdjacentAssistantBlocks
作为安全网,对时间窗内内容高度相似的相邻 assistant-reply block 保留更完整的一个。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(test): 补充 message-ledger 测试 fixture 缺失的 id 字段 (ISSUE-041)

tsconfig.vitest.json 类型检查报 TS2741:baseRealtime 对象缺少
MessageLedgerEntry 必需的 id 属性。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(chat-display): 修复跨 block 去重时间窗单位错误 + 消除 bigramJaccard 重复实现 (ISSUE-041);

- CROSS_BLOCK_TIME_WINDOW_MS=120000 误将毫秒值与秒级时间戳比较,实际窗口约 33 小时
  而非预期的 2 分钟;改为 CROSS_BLOCK_TIME_WINDOW_SEC=120(秒)
- 移除 chat-display.ts 私有的 computeCharBigrams / bigramJaccard,统一从 message.ts
  导入 bigramJaccardSimilarity,避免两处实现分叉

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041) (#437)

* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041);

- 新增 isSyntheticRunId 共享识别函数(覆盖 runId 缺失 / DEFAULT_RUN_ID / runId === threadId 三类合成回退标记),三层 dedup 一致放宽:
  1. message-ledger.ts::isSemanticEquivalentEntry:runId 不等时若任一侧 synthetic 则放行,threadId + role + 内容前缀 + origin 多元仍是必要约束;
  2. conversation-tree.ts fallback 段 runMatches:识别合成 runId 兼容分支,避免同内容 fallback message 被强制重建为重复节点;
  3. conversation-tree.ts collapseDefaultTurnDuplicates → collapseSyntheticTurnDuplicates:扩展为识别 runId === threadId 的合成 turn;时间窗判定改为 per-child timestamp vs concrete turn timeRange,多轮场景下不再误放过期 concrete turn。
- session-hydration.ts::fallbackRunId 注释 ISSUE-041 契约(保留兜底防御,等 Phase 2 后端代理层注入 runId 后再渐进移除)。
- 新增 16 例自动化回归(含 1 例反向回滚断言):
  · message-ledger A1-A5 + isSyntheticRunId 单元 + 端到端 ledger merge(共 7 例);
  · conversation-tree C1/C2/C3/C5 + D4 反向回滚(共 5 例);
  · session-hydration D1/D1+/D2/D3 端到端(共 4 例)。
- docs/issue.md 追加 ISSUE-041 全栈解析(含 refresh 自愈非对称的根因证据、多轮二阶恶化、Phase 2-4 路线图、诊断抓手与同类问题影响),闭环 ISSUE-040 Q3 长尾自识别。

回归状态:482 测试全绿 + tsc 0 错误;浏览器实机 5 场景 × 3 次验证清单见 .context/issue-041/validation-protocol.md,待用户已登录态 Chrome 桥接就绪后执行。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(rfcs): 新增 Phase 3 / Phase 4 架构 RFC 草稿(ISSUE-041 后续路线图);

- docs/rfcs/0001-conversation-architecture-refactor.md:Phase 3 架构重塑 RFC(Codex Thread→Turn→Item 数据模型 / 6 层去重金字塔精简到 3 层 / 抽象 utils/dedup/ + config/projection-thresholds.ts / 投影缓存 / 8 sub-PR 渐进迁移路线 / 兼容性回归与风险评估)。
- docs/rfcs/0002-ui-interaction-enhancements.md:Phase 4 UI 交互能力 backlog(Reasoning Panel + Sub-Agent 嵌套 / 工具进度 + 中断审批 / Conversation Branching + Timeline 增强;按用户优先级 1/2/3 分组,附实施依赖图与 Acceptance Criteria)。

均为 Draft 状态,待团队评审通过后启动多 PR 渐进迁移。本 commit 仅文档先行,不动代码。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 增强 synthetic turn 折叠相似度判定与时间窗整体吸收 (ISSUE-041);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 双层防御消除跨 runId 三气泡——泛化 turn 折叠 + 跨 block 去重 (ISSUE-041);

将 collapseSyntheticTurnDuplicates 泛化为 collapseOverlappingTurns:按 threadId 分组,
对 synthetic turn 与同组 concrete turn 时间重叠+内容覆盖的进行折叠(双 concrete turn
保留以防误折叠合法多 run);新增 chat-display 层 dedupeAdjacentAssistantBlocks
作为安全网,对时间窗内内容高度相似的相邻 assistant-reply block 保留更完整的一个。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(test): 补充 message-ledger 测试 fixture 缺失的 id 字段 (ISSUE-041)

tsconfig.vitest.json 类型检查报 TS2741:baseRealtime 对象缺少
MessageLedgerEntry 必需的 id 属性。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(chat-display): 修复跨 block 去重时间窗单位错误 + 消除 bigramJaccard 重复实现 (ISSUE-041);

- CROSS_BLOCK_TIME_WINDOW_MS=120000 误将毫秒值与秒级时间戳比较,实际窗口约 33 小时
  而非预期的 2 分钟;改为 CROSS_BLOCK_TIME_WINDOW_SEC=120(秒)
- 移除 chat-display.ts 私有的 computeCharBigrams / bigramJaccard,统一从 message.ts
  导入 bigramJaccardSimilarity,避免两处实现分叉

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复跨 runId 双气泡时间窗单位错误 + 消除 bigramJaccard 重复实现 (ISSUE-041);

fallback 路径从无条件移除改为内容覆盖检查——跨所有同 threadId keeper 逐 child
匹配,避免含独特历史内容的 synthetic turn 被误折叠。加强 C3 断言为
toHaveLength(2) + synthetictoBeDefined。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(conversation-tree): isSyntheticTurnNode 补充 "default" runId 识别对齐 isSyntheticRunId (ISSUE-041);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(ctl): 新增全套服务一键启停脚本 (#438)

* feat(ctl): 新增全套服务一键启停脚本 scripts/ctl.sh

支持 start/stop/restart/status/logs/build 子命令,覆盖依赖安装、
数据库迁移、前端构建、健康检查的完整生命周期。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(ctl): 修复 is_running 变量泄漏与并行 wait 退出码丢失;

- is_running() 中 pid_file 添加 local 声明,防止全局作用域污染
- 三处并行 wait 改为逐个检查退出码,任一子进程失败即报错中止

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(ctl): 修复健康检查不感知进程崩溃、路径逻辑重复与服务名校验缺失;

- wait_for_health 在 HTTP 轮询间隔中加入 is_running 检查,进程崩溃时立即返回失败
- is_running 改用 pid_file() 函数获取路径,消除硬编码重复
- cmd_logs 入口校验服务名是否属于 ALL_SERVICES,非法名称给出明确提示

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(ctl): 使用 exec 替代 eval 确保进程 PID 精确追踪与信号直达;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(kg): 知识图谱模块生产就绪改造 — 实体管理、混合检索、路径探索、统计面板 (#439)

* feat(kg): 知识图谱模块生产就绪改造 — 语料库级图谱、实体管理、混合检索、路径探索、统计面板

后端变更:
- 新增 GET /graph/entities 实体分页列表(类型筛选+名称搜索)
- 新增 GET /graph/entities/{id} 实体详情含出/入关系
- 新增 GET /graph/stats 图谱统计(实体数/类型分布/置信度/密度/度数)
- 重写 find_neighbors: 递归 CTE 在 kg_relations 上实现多跳遍历
- 重写 find_path: 递归 CTE BFS 在 kg_relations 上查找最短路径

前端变更:
- 重写 graph/page.tsx: 语料库选择器 + 构建/浏览全流程
- 新增 EntityListPanel: 表格视图+类型筛选+分页
- 新增 EntityDetailPanel: 实体详情+关系列表(出边/入边)
- 新增 SearchBar: 混合检索(语义+图结构)
- 新增 PathExplorer: 双实体选择+BFS路径查找
- 新增 NeighborExplorer: 1/2/3跳邻居展开
- 新增 GraphStatsPanel: 实体数/类型分布/置信度/密度/度数
- 新增 BuildHistoryList: 结构化构建历史卡片(状态徽章+统计+耗时)

文档变更:
- 扩展 user-guide.md §4.5 为完整知识图谱用户指引
- 更新 knowledge-graph.md §3 新增架构模式精炼(Cognee ECL/Graphiti 双时态)
- 更新 knowledge-graph.md §4 交付物清单

测试变更:
- 新增 test_graph_entity_service.py: 9 项单元测试覆盖实体列表/详情/Schema

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 修复知识图谱模块 CI 失败 — 类型错误、ID 前缀、测试 mock;

- 移除 NeighborExplorer 组件调用中不存在的 entityName prop(TS2322)
- 为 find_neighbors 返回的 GraphNode.id 补齐 entity: 前缀
- 重写 find_path 测试,mock session.execute 而非 find_neighbors

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 修复审查发现的 7 项问题 — 安全编码、状态管理、双向路径搜索;

- 路由 path params 加 encodeURIComponent 防路径遍历(3 个 route 文件)
- EntityDetailPanel: 用 loadedEntityId 派生 loading 状态,切换实体时正确展示加载态并清除旧数据
- EntityListPanel: 搜索输入 300ms 防抖,用 completedKey 派生 loading 状态
- GraphStatsPanel: 用 result 组合状态区分加载中/失败/成功
- NeighborExplorer: entityId 变更时重置 expanded/neighbors
- graph_repository find_path: 递归 CTE 增加反向遍历分支,与 find_neighbors 双向语义对齐

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 修复审查发现的遗留问题 — 常量提取、路径搜索、会话管理;

- 前端:提取 ENTITY_TYPE_COLORS 至 constants.ts,消除三处 TYPE_COLORS 残留引用(会导致运行时崩溃)
- 后端:修复 find_path 递归 CTE 中 path 追加错误(r.target_id → ps.target_id)
- 后端:get_stats 改为接收外部 db 会话,消除自建会话
- 后端:get_entity_detail 增加 corpus_id 可选过滤,增强数据隔离

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(memory): 记忆模块生产就绪化 — 巩固管线重构 + 事实提取 + 上下文集成 + 文档完善 (#440)

* feat(memory): 重构记忆巩固管线为三阶段智能架构并增强核心模块

- 重构 _simple_consolidate 为三阶段管线(分段→去重→存储),借鉴 Claude Code AutoDream 四阶段范式
- 新增 PatternFactExtractor 基于正则模式的对话事实自动提取(preference/profile/rule/custom)
- 新增 ContextAssembler 记忆上下文组装器,管理 token 预算分配(30%记忆/50%历史/20%系统)
- 新增 AsyncScheduler 应用层调度器回退,当 pg_cron 不可用时提供等效定时任务能力
- 增强 search_memory API 支持分页(limit/offset)和过滤(memory_type/date_from/date_to)
- 集成 ContextAssembler 到 perception.py 记忆搜索回退路径
- 新增 34 条单元测试覆盖事实提取和调度器(全部通过)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(memory): 补充工业框架对标分析与用户操作指南

- docs/memory.md §2.4 新增 Claude Code 记忆架构深度对标(AutoDream 四阶段整理、三重门控调度、四类型分类法、三层上下文压缩、漂移防御)
- docs/memory.md §2.5 新增 Agent Harness 设计模式对标(三层压缩管线、Skill 按需加载、Task Graph 持久化)
- docs/memory.md §2.6 新增 Negentropy 差异化定位总结表
- docs/user-guide.md §5.8-§5.12 新增记忆形成机制、保留分数解读、搜索最佳实践、自动化配置指南、故障排除

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 恢复巩固管线 metadata 中遗漏的 event_count 字段

三阶段管线重构后 metadata 字典遗漏了原有的 event_count 字段,
导致 test_memory_service_lifecycle 集成测试 KeyError 失败。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 修复 Code Review 反馈的 7 项问题

1. search_memory 的 memory_type/date_from/date_to/offset 过滤参数现在在 vector_search 和 ilike_search 中实际生效
2. context_assembler 的 lazy import 移至文件顶部,与同文件风格一致
3. _simple_consolidate docstring 从「三阶段」更正为「四阶段」(含事实提取)
4. api.py search_memories 的 total 字段添加 TODO 标记(需独立 COUNT 查询)
5. AsyncScheduler 失败时回退 last_run_at,允许尽快重试而非等完整 interval
6. PatternFactExtractor 三段重复遍历提取为 _match_patterns 辅助方法
7. _consolidate SQL 拼接改为参数化绑定 :lookback::interval,消除注入风险

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 修复 Code Review 反馈的 3 项问题

- offset 分页参数未透传到底层搜索方法,现已正确传递
- datetime.fromisoformat() 缺少校验,非法日期返回 400 而非 500
- AsyncScheduler 派发任务未被追踪,stop() 时一并取消在途任务

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 修复 Code Review 反馈的 2 项问题

- 巩固管线阶段 4 事实提取调用包裹 try/except,防止导入或工厂失败中断管线
- 搜索接口 total 字段改为 -1 标记"未知",避免分页客户端误读

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(memory): 记忆模块 Phase 2 — LLM 事实提取 + 摘要生成 + Token 精确计数 + 检索反馈闭环 (#442)

* feat(memory): 记忆模块 Phase 2 — LLM 事实提取 + 摘要生成 + 精确 Token 计数 + 检索反馈闭环

- TokenCounter: 基于 tiktoken cl100k_base 编码器精确计数,替代 LENGTH/4 粗略估算
- LLMFactExtractor: LLM 结构化输出事实提取,PatternFactExtractor 作为降级后备
- MemorySummarizer: LLM 生成结构化用户画像摘要,缓存至 memory_summaries 表(TTL 24h)
- SummaryService: memory_summaries 表 CRUD(upsert 语义)
- RetrievalTracker: 检索效果反馈闭环,记录检索事件 + 显式反馈 API
- ContextAssembler: 优先注入摘要,tiktoken 精确 token 计数
- 新增 Alembic migration 0013/0014(memory_summaries + memory_retrieval_logs)
- 新增 MemorySummary + MemoryRetrievalLog ORM 模型
- 11 条新增单元测试,62 条全部通过,零回归

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(memory): Phase 2 文档沉淀 — 两级提取策略 + 摘要巩固 + 精确计数 + 检索反馈 + 新增文献

- §4.2 扩展为两级事实提取策略说明(LLMFactExtractor + PatternFactExtractor)
- §5.4.1 新增摘要巩固策略(记忆再巩固理论 + 5 项工程对标)
- §6.3 更新 Token 估算为 tiktoken BPE 精确计数
- §6.5 新增检索效果反馈闭环(Rocchio + LTR + LongMemEval 评估维度)
- §15 新增 6 篇参考文献(Sennrich 2016, Sara 2015, Rocchio 1971, Burges 2005, Mem0, Letta)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 修复 LLM 事实提取 prompt 类型名不匹配 + 检索指标 SQL 聚合优化;

- prompt 模板中 "pref" 改为 "preference",与 _VALID_FACT_TYPES 验证器对齐,避免 LLM 输出被静默降级为 "custom"
- get_effectiveness_metrics 改用 SQL COUNT+CASE 聚合,避免将全量日志行加载到 Python 内存

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* refactor(memory): Review 反馈修复 — 检索日志可观测性 + query 透传 + 模型配置去重;

1. 检索追踪 except 从 silent pass 改为 logger.debug,使故障可诊断
2. _record_access 新增 query 参数并从所有调用点透传,消除空 query 问题
3. 提取 _resolve_model_config 为共享工具 engine/utils/model_config.py,
   LLMFactExtractor 和 MemorySummarizer 统一引用,消除 DRY 违规
4. 同步更新单元测试 mock 路径

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 修复图谱双写数据流断链 — 一等公民表对齐 (#441)

* fix(kg): 修复图谱双写数据流断链 — 一等公民表对齐

- create_relation() 新增写入 kg_relations 一等公民表,保留 JSONB 过渡兼容
- get_graph() 优先从 kg_entities + kg_relations 读取,空时回退 JSONB
- clear_graph() 增加 kg_entities/kg_relations 表清理
- build_graph() 完成后调用 KgEntityService.batch_sync_from_graph_build()
- 更新 test_graph_repository 适配新读写路径

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(kg): 新增 PageRank 实体重要性评分与 RRF 混合检索

- 新增 graph_algorithms 模块,基于 NetworkX 实现 PageRank (Brin & Page, 1998) 计算,
  结果持久化至 kg_entities.importance_score
- 混合检索支持 Reciprocal Rank Fusion (Cormack et al., SIGIR 2009) 模式,
  可通过 GraphQueryConfig.use_rrf / rrf_k 配置,向后兼容线性加权模式
- 图谱构建完成后自动触发 PageRank 计算
- 实体列表支持按重要性排序(sort_by=importance)
- 统计面板展示 Top 5 PageRank 实体
- 图谱可视化节点半径映射 PageRank 分数,突出重要实体

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(kg): 新增 Louvain 社区检测与图谱可视化增强

- 新增 compute_louvain() 算法,基于 NetworkX 内置 Louvain (Blondel et al., 2008)
  在无向投影图上运行社区检测,结果持久化至 kg_entities.community_id
- 图谱构建完成后自动触发 Louvain 计算(紧接 PageRank 之后)
- 统计面板新增社区分布(community_count + community_distribution)
- 实体列表和详情响应包含 community_id 字段
- 图谱可视化节点按社区着色(Tableau 10 色盲友好调色板)
- 统计面板展示 Top 8 社区分布柱状图
- 实体表格新增社区列,显示色块标识
- 显式声明 networkx>=3.0 依赖(此前为隐式运行时导入)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 新增 Alembic migration 0015 — 添加 importance_score 和 community_id 列

CI 集成测试失败根因:ORM 模型新增了 importance_score (PageRank) 和 community_id (Louvain)
列,但缺少对应的 Alembic migration,导致测试数据库 schema 不匹配。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 修复 Review 反馈的三个问题

1. RRF 搜索 graph_score 恒为 0 — 将 importance_score 写入 entity_data
2. PageRank/Louvain 逐条 UPDATE — 改为 VALUES CTE 批量更新
3. 一等公民表路径缺 app_name 过滤 — 文档明确 corpus 级去重设计意图

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(memory): Phase 2+ 增强 — 反馈闭环闭合 + Query-Aware 组装 + 近重复检测 + 测试覆盖 (#443)

* test(memory): Phase 2 组件测试覆盖 — TokenCounter / SummaryService / RetrievalTracker / MemorySummarizer;

新增 39 个单元测试用例,覆盖 Phase 2 四个核心组件:
- TokenCounter: 精确计数、空输入、幂等性、异步一致性、单调性(蜕变测试)
- SummaryService: upsert/get/delete CRUD 路径
- RetrievalTracker: 检索日志、引用标记、反馈记录、效果指标计算
- MemorySummarizer: 摘要生成、TTL 缓存命中/过期、LLM 失败降级、重试

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(memory): Phase 2+ 增强 — 反馈闭环闭合 + Query-Aware 组装 + 近重复检测 + 文档沉淀;

Gap 1 反馈闭环:
- _record_access 修复 user_id/app_name 透传(此前始终为空字符串)
- PostgresMemoryService 存储 _last_retrieval_log_id 供下游消费
- ContextAssembler 注入 mark_referenced 隐式反馈信号(RLHF[33])
- API 新增 POST /memory/retrieval/feedback 和 GET /memory/retrieval/metrics

Gap 2 Query-Aware:
- assemble() 新增 query/query_embedding 可选参数
- _call_get_context_window 传递 7 个参数(含 p_query, p_query_embedding)
- SQL 函数 NULL safe 退化:无 query 时保持纯 retention_score 排序
- 隐式反馈标记在上下文组装成功后触发

Gap 3 近重复检测:
- _is_duplicate 阈值从 0.9 降至 0.85(Henzinger[40])
- 新增 Jaccard 词重叠二次校验(0.80-0.85 区间,Broder[37])
- FactService 新增 merge_similar_facts() 语义去重方法

文档沉淀:
- docs/memory.md 权威源文件索引扩充 Phase 2 组件
- §15 追加 13 篇参考文献 [31]–[43]

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 修复 merge_similar_facts 过度删除 + retrieval_log_id 并发安全问题;

- merge_similar_facts: 锚点事实被删除后立即 break 内层循环,避免基于已删除 embedding 继续比对导致误删
- _record_access: 移除 _last_retrieval_log_id 实例属性,改为返回 log_id,消除共享可变状态的并发竞态
- ContextAssembler.assemble: memory_service 参数改为显式 retrieval_log_id,调用方直接传入

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(kg): Phase 3 生产就绪增强 — 增量构建 + 语义去重 + 管线健壮性 + 查询缓存 (#444)

* feat(kg): Phase 3 生产就绪增强 — 增量构建 + 语义去重 + 管线健壮性 + 查询缓存

Gap 3 [P1] 构建管线健壮性 (Nygard, 2018; Majors, 2022):
- Migration 0016: kg_build_runs 增加 progress_percent + warnings 列
- build_graph: 批处理循环进度上报、LLM 提取失败重试 1 次、算法失败警告累积
-…
ThreeFish-AI added a commit that referenced this pull request May 9, 2026
…iew #1);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
ThreeFish-AI added a commit that referenced this pull request May 9, 2026
* feat(knowledge-base): Knowledge.document_id FK + 孤儿清算 CLI (Phase 3);

ISSUE-078 Phase 3 — DB Schema 防御层 + 历史脏数据一次性清算。Phase 1 修计数口径、
Phase 2 修应用层级联、Phase 3 在 DB 层加 FK ON DELETE CASCADE 兜底,三层防御
正交可独立回滚。

变更:
- alembic 0030: ADD COLUMN knowledge.document_id UUID NULL +
  FK fk_knowledge_document_id REFERENCES knowledge_documents(id) ON DELETE
  CASCADE + 部分索引 ix_knowledge_document_id WHERE document_id IS NOT NULL;
  仅加列与约束、不做数据变更(避免大表 UPDATE 长锁);downgrade 仅 DROP COLUMN
- ORM 同步: models/perception.py Knowledge.document_id Mapped[UUID|None]
- KnowledgeChunk dataclass: 加 document_id 字段;types.py
- 写入路径 stamp: _ingest_text_with_tracker 加 document_id 参数,单点
  dataclasses.replace stamp 到每个 chunk;repository.add_knowledge values 加
  document_id 字段。仅 2 个 ingest 入口(execute_ingest_url_document_pipeline /
  execute_ingest_file_pipeline)传入 document_id,其余 10 个入口(纯文本、URL、
  replace、rebuild、KG)保留 None
- 独立 CLI scripts/cleanup_orphan_knowledge.py:
    uv run python -m negentropy.scripts.cleanup_orphan_knowledge \
      --dry-run | --commit [--corpus-id ...] [--app-name ...] [--json]
  三步流水线: 回填 document_id → 按 corpus 分组报告四档计数 → --commit 才
  真正 DELETE(白名单 source_uri 形态防误删);不放进 alembic 迁移因为
  DELETE 不可逆需 dry-run + 审批
- 观测函数 count_orphan_knowledge: 与 CLI 共享过滤口径,cron 接入将
  total_orphans 上报为 metric negentropy.knowledge.orphan_count{corpus_id}

dev DB 实地验证:
- 在 user 真实数据上跑 --dry-run 报告 Harness Engineering corpus
  total=849, would_delete=0;--commit 后 849 条 Knowledge.document_id 全部
  回填,与对应 KnowledgeDocument 建立 FK 关联
- Phase 1 → Phase 3 三层防御端到端在用户实际数据上闭环

测试: test_phase3_document_fk.py 8 场景覆盖 ORM 字段读写、DB 层 FK CASCADE
(直接 DELETE knowledge_documents 行触发 Knowledge 级联清理)、CLI dry-run/
commit、KG NULL source_uri 保留、非白名单 URI 形态保留、观测函数、migration
round-trip;既有 67 项单测无回归;alembic upgrade/downgrade 已在 dev DB 验证

详见 docs/issue.md ISSUE-078 Phase 3 补充章节。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(knowledge-base): cleanup CLI backfill 改用标量子查询优先选取 active doc (review #1);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(knowledge-base): 修复 CI 集成测试三处失败 (review #2);

- conftest: 补丁 storage.service / cleanup_orphan_knowledge 的模块级
  AsyncSessionLocal 引用(from-import 绑定问题),修复 asyncpg 事件循环边界
  RuntimeError
- _sync_document_chunk_stats: 包裹 try/except 降级为 warning,避免纯单元
  测试(FakeRepository 无真实 DB)触发 DB 连接崩溃
- _backfill_sql: 改回 UPDATE ... FROM + DISTINCT ON 子查询,仅更新有文档
  匹配的行(孤儿行自然排除),修复 backfilled 计数断言失败

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(knowledge-base): 修复 CI 集成测试两处失败 (review #3);

- _backfill_sql: 子查询内 scope 条件引用外部别名 k → 改为 k_sub,
  修复 PG UndefinedTableError
- conftest: 补丁 knowledge.api 的模块级 AsyncSessionLocal 引用,
  修复 _scenario_soft_delete_archives 调用 list_corpora 时的事件循环边界错误

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
ThreeFish-AI added a commit that referenced this pull request May 17, 2026
…识管理统一入口(100 PRs / 843 文件) (#560)

* feat(agent-defs): 主 Agent 入库 + 按 DB 读 instruction + 模型选择回退 (#420)

* fix(agent-defs): 修复 Agent 加载路径 + 主 Agent 纳入 Interface Sync + 运行时按 DB 读 instruction;

- cli.py: --reload_agents 改用 Path(__file__) 推导的绝对路径,杜绝 cwd 依赖导致的「src/negentropy/negentropy」双重段错误;
- subagent_presets: 新增 NegentropyEngine root payload(adk_config.kind="root"),Sync 后 DB 出现主 Agent 行;
- sync API: 循环写入 config.kind,末尾调 invalidate_cache(prefix="subagent:") 批量失效;
- SubAgentResponse: 新增顶层 kind 字段(root/subagent),供前端置顶 + 徽章;
- model_resolver: 抽取 _load_subagent_row 共用单行查询,新增 resolve_subagent_instruction;
- _dynamic_instruction: 新增 InstructionProvider 工厂,root + 5 子 Agent 的 instruction 接入运行时 DB 读取;
- 测试: 更新 test_subagent_presets 覆盖 root payload + kind 断言;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-llm): 修复无 Session 时模型选择回退 + SubAgents 列表 Root 置顶徽章;

- home-body: 新增 pendingLlmRef,改写 handleSelectedLlmModelChange 与 Effect 1,
  使「无 session 选模型→建 session→自动发送」全流程保持选择不丢失;
- SubAgents page: 按 kind="root" 置顶排序,Sync 按钮文案从「Sync Negentropy 5」改为「Sync Negentropy」;
- SubAgentCard: Root Agent 显示 violet 色 Root 徽章;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(model-resolver): SubAgent 行缺失/未启用补回 60s TTL 负命中缓存;

回归点:重构 `_resolve_subagent_row` 时把空占位写入移到了 `loaded is None`
判断之后,导致禁用 Faculty 与未 Sync 环境下每次 LLM 请求都触发一次 DB 查询。
本次在 `loaded is None` 分支补 `_cache[cache_key] = ("", {"i": ""}, now)`,
让负命中同样落入 60s TTL,避免重复 DB 压力。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-llm): pending 模型选择仅对 startNewSession 新 id 消费;

回归点:Effect 1 的 pending 转移分支会在「首次进入既有 session」时触发,
把无 session 阶段的 pending 模型写入该 session 的 perThreadLlmRef,
并让 Effect 2 跳过 snapshot 初始化,导致服务器端记忆模型被静默替换。

修复方式:
- 新增 `pendingLlmTargetIdRef` 仅记录 startNewSession 返回的新 id;
- 通过 `startNewSessionWithLlmTarget` 包装内联调用与 `onNewSession` 两条路径;
- Effect 1 仅在 `sessionId === pendingLlmTargetIdRef.current` 时转移 pending,
  其余进入既有 session 的分支主动丢弃 pending,让 snapshot 正常生效。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(knowledge): 修复 KB Retrieve 全屏空白(前端聚合 rejection × 后端 hybrid/rrf 降级 × 502 上游错误码 × 诊断仪器化) (#421)

* fix(knowledge): 修复 Knowledge Base Retrieve 全屏空白(前端聚合 rejection + 后端 hybrid/rrf 降级 + 502 错误码 + 诊断日志);

双层 Bug 同因联修(详见 docs/issue.md ISSUE-026):
1. 前端 searchAcrossCorpora 旧实现以 Promise.allSettled 仅取 fulfilled,rejected 静默丢失,导致全部 Corpus 失败时返回 {count:0,items:[]} 走"成功路径"使 UI 空白且无任何提示——本次改为聚合三态(全成功/部分失败/全失败),SearchResults 类型扩展 errors[],handleRetrieve 对部分失败 toast.warning 透出原因;
2. 后端 service.search hybrid/rrf 旧实现未捕获 EmbeddingFailed,外部 Embedding 上游故障直接 500,丧失"keyword 仍可用"的优雅降级——本次 hybrid 失败回退 keyword-only、rrf 失败走与 not embedding_fn 等价的回退路径,semantic 仍传播以保留显式失败语义;
3. api.py _map_exception_to_http 拆分 EmbeddingFailed 分支映射到 502 Bad Gateway(保留 EMBEDDING_FAILED code),与 SearchError 自身错误的 500 区分,便于前端识别"上游修复后再试"语义;
4. embedding.py 调用 litellm 前后增加结构化诊断日志:api_base_host(脱敏 path/credentials 仅留 host)+ input_count + text_preview + kwargs_keys;失败附 upstream_response_text(沿异常链 __cause__/__context__ 提取 MaskedHTTPStatusError.text,已被 litellm 脱敏 URL,限长 500 字节);
5. 测试锁定:tests/unit_tests/knowledge/test_search_resilience.py 5 例(hybrid/rrf 降级 + semantic 传播 + EmbeddingFailed→502 + SearchError→500)+ tests/unit/knowledge/searchAcrossCorpora.test.ts 3 例(allSettled 三态);
6. docs/issue.md 追加 ISSUE-026,含后续防范(Promise.allSettled 必须聚合 rejection / vendor 失败必须 502 / hybrid 必须有降级路径 / vendor 调用必须 host+upstream_text 双信号)与同类问题影响清单。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(knowledge): searchAcrossCorpora 聚合保留 KnowledgeError code 并修正 _map_exception_to_http docstring;

Review #1(前端契约): SearchResultError 仅透 message 会丢弃 KnowledgeError.code(如 EMBEDDING_FAILED),削弱本次 502/500 拆分对前端"上游修复 vs 自身错误"的可分流价值——本次扩展 SearchResultError 增加可选 code,rejection instanceof KnowledgeError 时回填;全失败分支由 throw new Error 改为 throw new KnowledgeError(aggregatedCode, msg, {errors}),code 一致时透传原 code、混合时退化为 AGGREGATED_SEARCH_ERRORS,既保留分流能力又携带逐条失败明细;新增 1 例同 code 透传 + 1 例混合 code 退化的单测,全部 4 例通过。

Review #2(后端文档): api._map_exception_to_http docstring 仍只列 400/404/409/500,与新增 EmbeddingFailed→502 分支不一致;本次补 "502: 上游服务错误(vendor / Embedding 等外部依赖)" 一行,避免后续维护者按旧映射加分支。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(wiki-favicon): 修复 negentropy-wiki 站点 favicon.ico 单分辨率畸形导致浏览器回落默认地球图标; (#423)

- 根因:apps/negentropy-wiki/src/app/favicon.ico 是单分辨率畸形 ICO(file 输出 256x-1,高度字节 0xFF),且源图 logo.png 为非方形 800x798,导致 Chrome/Firefox/Safari 解析失败、tab 回落默认地球图标;
- 修复:用 Pillow 对 logo.png 做透明 padding 至 800x800 方形,再生成多分辨率 ICO(16/32/48/64/128/256 共六档)覆盖原文件;体积从 269KB 降至 118KB;
- 验证:file 输出 6 icons; pnpm build 后 .next/standalone 内 favicon route + body + meta 完整;pnpm start 后 curl /favicon.ico 返回 200 image/x-icon,HTML 自动注入 <link rel="icon">;
- 防范:docs/issue.md 追加 ISSUE-027,沉淀「ICO 必须方形 + 多分辨率」工程约束与 Pillow 流水线模板,禁止「原图直裹 ICO 头」反模式;
- 不动:layout.tsx / next.config.ts / start-production.mjs,保留 App Router metadata 自动注入路径,最小干预。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* feat(mcp-resources): 接入 Resource Templates 并贯通 PDF 图片到 Wiki Markdown (#422)

* feat(mcp-client): 接入 MCP Resource Templates 与同会话动态资源拉取;

新增 McpResourceTemplate 模型与 Alembic migration 0012,扩展 McpClientService 在
连接发现阶段并发调用 list_resource_templates(旧 server 不支持时静默兜底,不
阻断 tools 发现),新增 call_tool_and_resolve_resources:在同一 ClientSession 内
完成工具调用与所有 resource_link URI 的并发拉取(Semaphore 限流 4,return_exceptions
保证单条失败不击穿主流程)。这是接入 Negentropy Perceives 动态 FileResource
(perceives://pdf/<job_id>/<filename>)的协议层基石——动态实例的生命周期与工具
会话强绑定,必须在 session 关闭前完成 resources/read 才能避免事后失链。

Interface API 同步:load_mcp_server_tools 端点扩展为 capability 全量同步(tools
+ resource_templates,软删除已下线的 templates),LoadToolsResponse 新增
resource_templates 字段(向后兼容),新增 GET /mcp/servers/{id}/resource-templates
端点;list_mcp_servers 拆解为分段计数避免 JOIN 笛卡尔积;McpServerResponse 暴露
resource_template_count 给前端展示。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(perceives-resources): PDF 图片资源端到端贯通到 GCS 与 Wiki Markdown;

把 Perceives MCP 工具调用返回的 ResourceLink 接入既有提取流水线(Ingest 与
Re-Parse from GCS),让 PDF 图片资源在主仓 ↔ Perceives 之间通过 MCP 协议
完整贯通:

- 提取层(extraction.py):新增 _extract_resource_link_assets 把 ResourceLink
  与同会话 read_resource 拉取的 base64 配对为 ExtractionAsset;_call_tool_with_plan
  改用 resolve_resource_links=True 路径,确保动态 URI 不会因会话关闭失链;
  _build_success_result 接收 resolved_resources / resource_errors,按 "warn +
  占位" 容错策略合并 assets 并标记 partial_failure 不阻断主入库;新增
  _rewrite_markdown_image_links 在 Markdown 写入 GCS 之前把相对路径图片引用
  重写为 /api/documents/{doc_id}/assets/{filename},重写采用 capture group 偏移
  以避免 alt 文本含同名 src 时误替换。

- Knowledge API:新增 GET /knowledge/wiki/documents/{document_id}/assets/{filename}
  公开端点,filename 严格白名单 ^[A-Za-z0-9._-]+$ 与 180 字符上限;鉴权策略与
  既有 wiki entry content 端点对齐——仅放通至少被一条 WikiPublicationEntry
  引用的 document,避免持任意 doc_id 拖走未发布文档资产。

- 前端 MCP 卡片(negentropy-ui):新增 Resource Templates 折叠区与 ResourceDetailPanel,
  视觉与 Tools 区完全镜像;page.tsx 在 tools:load 响应中同步消费
  resource_templates 段,状态合并到 ServerWithTools;动态实例(带 job_id)
  按设计不入卡片。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(mcp-client): Resource Templates 同步加 capability flag,避免静默兜底误清空模板表;

`_discover_on_transport` 对 `list_resource_templates` 的所有异常都会静默兜底返回空列表(兼容旧 server 与瞬态错误),但 `load_mcp_server_tools` 会把空列表当作权威结果裁剪 stale 行,导致一次网络抖动或 server bug 即抹掉全部模板;同时与 tools 同步"只增量更新、不裁剪"的语义不对称。

- `McpConnectionResult` 新增 `resource_templates_listed: bool`,仅在 `list_resource_templates` 成功返回时为 True;
- `load_mcp_server_tools` 仅在该 flag 为 True(权威空列表)时才裁剪 stale 模板,未支持/错误场景保留既有 DB 行;
- 单元测试覆盖 flag 在权威空列表与异常兜底两种路径下的取值。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(mcp-card): 单测 server fixture 补 resource_template_count 修 UI Type Checks;

`McpServer` 类型新增的必填字段 `resource_template_count` 未同步到 `McpServerCard.test.tsx` 的 server 固件,导致 ui-quality / UI Type Checks 在 5 处 `<McpServerCard server={...}>` 调用上报 TS2741。

- 在 server 固件加 `resource_template_count: 0`,spread 派生用例自动获得新字段。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(knowledge): 查询时 honor Corpus 自配 embedding 模型,修复 query/index 模型不一致 (ISSUE-028) (#424)

search() 原直接使用实例化时锁定的 self._embedding_fn(全局默认 gemini/text-embedding-004),
未读 corpus.config.models.embedding_config_id;而 _attach_embeddings 索引侧已按 corpus pin 走
专属 fn。两侧不对称导致:用户在 Corpus Settings 已切到 openai/text-embedding-3-small(1536 维),
索引按 OpenAI 生成,查询仍走 Gemini 全局默认经 localhost:3392 翻译代理报 400。

修复:
- 新增 _resolve_embedding_fn(corpus_config) 助手,corpus pin 优先 → 退回 service 默认 fn;
- search() 入口加载 corpus_config + embedding_fn 本地变量,rrf/hybrid/semantic 三分支替换;
- ISSUE-026 keyword 兜底 + 502 映射 + 诊断日志原样保留,零回归;
- 新增 5 例单元测试覆盖 corpus pin 命中/落空/兜底/rrf/semantic 上抛,577 全绿。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* fix(agent-llm): 修复 Home Send 时 LLM 凭证未从 DB 读取导致 AuthenticationError (#425)

* fix(docs): 同步文档启动命令与 cli.py 修复,消除 Home Send 500 复发路径;

cli.py 的 agents_dir 已在 35204ff 从 src/negentropy 修正为 src,
但 README / docs 下 4 个文件 7 处仍写 --reload_agents src/negentropy,
用户照文档启动复现 ValueError: Agent not found 500。
统一替换为 uv run negentropy serve(SSOT),
追加 ISSUE-029(文档漂移)与 ISSUE-030(SubAgents root Agent 防回归)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(agent-llm): 修复 Home Send 时 LLM 凭证未从 DB 读取导致 AuthenticationError;

DynamicRootLiteLlm/DynamicSubagentLiteLlm 在 ContextVar 或 sub_agents.model
为空时直接返回 None,回退到构造时无 api_key 的硬编码实例,绕过了 DB 中
已配置的 vendor_configs 凭证。现在始终通过 resolve_llm_config() 从 DB
解析默认模型的完整凭证(含 api_key)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复长耗时回复双气泡 + 首条未格式化 (ISSUE-031); (#426)

ADK 仅持久化 partial=false 终态事件,realtime 与 hydration 在
同一逻辑消息上派出不同的 messageId(首个 partial id vs 终态 id)。
isSemanticEquivalentEntry 的 8s 时间窗在长耗时回复下硬拒绝,导致
ledger 双 entry → events 过滤失败 → conversation tree 双节点 →
UI 渲染双气泡(首条因 streaming-markdown 尾部判定走 raw text 分支)。

修复 (最小干预 + 正交分解):
- message-ledger.ts: 内容严格相等时跳过 8s 时间窗硬拒绝。
- conversation-tree.ts: assistant 已收尾节点在内容严格相等时
  也允许 findMatchingTextNodeId 命中复用,作为防御性收敛。
- 三层回归测试覆盖 ">8s 跨度 + messageId 不同 + 内容严格相等"。

UI 全量 70 文件 396 测试通过;typecheck/typecheck:test/eslint 零报错。
docs/issue.md 沉淀 ISSUE-031;CHANGELOG.md 同步条目。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* fix(home-chat): 修复 Home 对话 title 凭证缺失与 OTLP logs/metrics 404 双联缺陷 (#427)

* fix(home-chat): 修复 Home 对话 title 凭证缺失 + OTLP logs/metrics 404 双联缺陷;

(1) SessionSummarizer 同步 __init__ 在 60s 缓存 miss 时回退到无 api_key 硬编码默认,
导致 LiteLLM AuthenticationError;改为 async classmethod create() 经 resolve_llm_config()
从 DB 读取完整凭证(与 commit 8ce35d5 修复 DynamicRootLiteLlm 同 SoT),调用方
session_service._generate_title_for_session 切换为 await SessionSummarizer.create(),
对 resolver 返回 kwargs 做防御性浅拷贝避免与 60s 缓存层耦合。

(2) ADK 上游 _get_otel_exporters() 把 OTEL_EXPORTER_OTLP_ENDPOINT 视为 OTLP 三件套
总开关,无差别注册 OTLPSpanExporter / OTLPMetricExporter / OTLPLogExporter;后两者
对 Langfuse 不存在的 /v1/metrics、/v1/logs 上报触发 SPA 404 SSR 错误页(每次对话
反复输出大段 HTML)。bootstrap.py 新增 _install_noop_otel_logs_metrics_providers()
在 OTel env var 设置后立即抢注无 processor / 无 reader 的 SDK Logger/Meter Provider,
利用 OTel SDK Once-lock 让 ADK 后续 set_*_provider 静默 no-op,从而阻断 logs/metrics
上报;TracerProvider 链路与 OTEL_EXPORTER_OTLP_HEADERS 不动,traces 仍正常进入 Langfuse。

新增 tests/unit_tests/engine/test_summarization.py(3 例)+
tests/unit_tests/observability/test_otel_noop_providers.py(3 例,子进程隔离 OTel 全局
状态)锁定回归。CHANGELOG / docs/issue.md 沉淀 ISSUE-031(title 凭证缺失)与
ISSUE-032(OTLP logs/metrics 404)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(otel-noop): 移除 _sdk_config hasattr 兜底,让 SDK 私有属性变更显式触发回归;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(session-title): 修复 DummySummarizer 缺失 async create() 导致集成测试 AttributeError;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(bootstrap-otel): 消除 ADK Web 启动期 OTel Override Provider 双 WARNING (ISSUE-034); (#428)

将 ISSUE-033 的「抢占式 set_logger_provider/set_meter_provider」改为 patch
`google.adk.telemetry.setup._get_otel_exporters`,让其只返回 traces 的
span_processors,metric_readers/log_record_processors 永久置空。ADK
maybe_set_otel_providers 的 if 分支由此天然短路,set_*_provider 根本不被
调用,从源头消除 OTel SDK 的 "Overriding of current ... is not allowed"
WARNING;traces 链路、ADK ApiServerSpanExporter、TracingManager、LiteLLM
"otel" callback 行为完全不变。配套更新 3 个子进程隔离单测验证新语义,
并在 docs/issue.md 追加 ISSUE-034 完整记录。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* feat(e2e-auth): 浏览器验证协议落地 + Playwright 会话复用贯通 Google OAuth (#429)

* docs(browser-validation): 落地浏览器验证协议并补 ISSUE-034

- AGENTS.md(即 CLAUDE.md symlink)新增"Browser Validation Protocol"子节,
  约定登录态浏览器验证必须复用用户常用 Chrome 会话,禁止 sandbox 浏览器
  通过 Google 同意屏,明确凭证守则与三步连通性自检;
- 新建 docs/agents/browser-validation.md:含三种 MCP 浏览器工具能力对照、
  Mermaid 选型决策图、storageState 工作时序、风控应对、IEEE 引用;
  实测附注 chrome-devtools MCP 在 macOS 默认即可复用用户主 profile 登录态;
- docs/issue.md 追加 ISSUE-034,记录 sandbox 浏览器走 Google OAuth 被拦
  的表因/根因/处理方式/防范,便于跨上下文复用。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(e2e-auth): Playwright 会话复用以贯通 Google OAuth E2E

- playwright.config.ts 在 PLAYWRIGHT_AUTH=1 时启用两个项目:
  * setup(headless: false,匹配 *.setup.ts),让用户在弹出窗手动登录;
  * chromium-authenticated(dependencies: ['setup']),使用 storageState
    复用一次性人工登录的会话;
  支持 PLAYWRIGHT_STORAGE_STATE 与 PLAYWRIGHT_USER_DATA_DIR 覆盖默认;
  现有 chromium project 加 testIgnore 排除 .setup.ts,CI/默认行为零变;
- 新增 tests/e2e/auth.setup.ts:打开 /auth/google/login,5 分钟内允许
  用户在 Google 同意屏中手动完成登录,回跳后断言 /api/auth/me 2xx,
  写入 storageState;
- .gitignore 追加 apps/negentropy-ui/.auth/ 与 .userdata/,
  防止会话凭证随分支推送外泄。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(e2e-auth): 修复 OAuth setup 早退与 authed spec 双跑;

- auth.setup.ts: waitForURL 谓词追加 host 约束,避免在跳往 accounts.google.com
  瞬间因 pathname 已离开 /auth/google 而误判完成,导致 /api/auth/me 在用户登录前
  失败、storageState 永不写出。
- playwright.config.ts: 基础 chromium project 的 testIgnore 追加
  /.*\.authed\.spec\.ts$/,防止 PLAYWRIGHT_AUTH=1 时同一份认证 spec 在
  chromium-authenticated 与 chromium 中各跑一次(后者无 storageState 必失败)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复 Home 双气泡复发与 LLM 模型未 Send 即刷新丢失 (ISSUE-032/033); (#430)

ISSUE-032 (双气泡复发,与 ISSUE-031 正交):
- 根因:root agent prompt 主动导航 + log_activity tool 让 ADK 走双轮 LLM 调用,
  两轮各自带独立 messageId 走完整 TEXT_MESSAGE_* 三件套,UI 在同一
  assistant-reply bubble 内并列渲染两段近重复文本。
- 修复:utils/chat-display.ts::dedupeRedundantTextSegments 在
  buildAssistantReplyBlock 出口对同一 reply 内的 text segment 做字符二元组
  Jaccard 相似度计算,相似度 ≥ 0.5 且双方长度 ≥ 30 时丢弃前段、保留信息更
  完备的最终段。tool-group / reasoning / error 顺序不动。
- assistant-reply.message.content 联动重组,复制时也拿到折叠后的内容。

ISSUE-033 (LLM 模型未 Send 即刷新丢失):
- 根因:后端事实源 session.state.selected_llm_model 仅在 /run_sse 时随
  state_delta 写入,未 Send 时不更新;前端 perThreadLlmRef 是 useRef
  刷新即丢;snapshotForDisplay 也无值,回退到 default。
- 修复:app/home-body.tsx 顶部新增 readPersistedLlmModel /
  writePersistedLlmModel (typeof window 守卫 + try/catch SSR 安全);
  handleSelectedLlmModelChange 即时落盘到 localStorage;Effect 1 优先
  从 localStorage 还原;Effect 2 命中 snapshot 时同步回写 localStorage,
  让「后端 state ↔ localStorage」互为镜像。既有 forwardedProps.selected_llm_model
  在 Send 时仍写后端 state,跨设备一致性最终收敛。

测试:
- 新增 2 例 chat-display.test.ts 用例:折叠近重复段 + 差异度大不被折叠
- UI 全量 70 文件 398 测试通过;typecheck/typecheck:test/eslint 零报错

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* fix(bootstrap-otel): 消除被丢弃 PeriodicExportingMetricReader 守护线程的周期 WARNING (ISSUE-038) (#431)

* fix(bootstrap-otel): 消除被丢弃 PeriodicExportingMetricReader 守护线程的周期 WARNING (ISSUE-038);

ISSUE-034 的 patch 调用 original() 后再丢弃 metric_readers /
log_record_processors,但上游 _get_otel_exporters 已构造
PeriodicExportingMetricReader 并启动 60s 守护线程——reader 未注册
到 MeterProvider 导致每 tick 触发 "Cannot call collect on a
MetricReader ..." WARNING。改为绕过 original(),直接复用
_get_otel_span_exporter() 仅构造 traces span processor,根源
避免 OTLP metrics/logs exporter 被实例化。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(bootstrap-otel): 修正 _disable_adk_otel_logs_metrics_exporters docstring 中的过期 hooks 引用;

旧 docstring 沿用重构前 `hooks = original()` 的中间变量术语,但新实现已不再调用 `original()`,函数体内也没有 `hooks` 绑定。
更新指引为「恢复 _get_otel_exporters 原函数闭包」或「直接构造完整 OTelHooks」,避免误导后续维护者寻找已不存在的对象。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复 Home 双气泡盲区与刷新后消息乱序 (ISSUE-039) (#432)

* fix(home-chat): 修复 Home 双气泡盲区与刷新后消息乱序 (ISSUE-038);

- chat-display: dedupeRedundantTextSegments 增加四层判定(精确匹配 / 严格前缀 / 等价内容 / Jaccard),覆盖 ADK 双轮 LLM 短回复(如 "Pong!")的双气泡盲区。
- session-hydration: mergeEventsWithRealtimePriority 交换参数顺序,让 realtime 事件覆盖 hydrated;TEXT_MESSAGE_CONTENT 的 eventKey 时间戳改用 toFixed(3) 消除浮点抖动导致的同一事件重复保留。
- message-ledger: MessageLedgerEntry 新增可选 sourceOrder 作 createdAt 相同时的稳定 tiebreaker,替代 UUID localeCompare 的随机字典序;抽出 compareLedgerEntriesByTime 复用,类型保持向后兼容(缺省回退 Number.MAX_SAFE_INTEGER)。
- 新增 5 项单元测试覆盖:短回复精确匹配、前缀含尾部追加、Jaccard 长文本、eventKey 浮点稳定、sourceOrder 稳定排序;docs/issue.md 增补 ISSUE-038 摘要。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(home-chat): 补 mergeEventsWithRealtimePriority 生命周期事件覆盖回归用例;

针对 ISSUE-039 第 3 项修复(mergeEventsWithRealtimePriority 参数顺序交换)
原有 RUN_STARTED 类生命周期事件用例缺位——之前的 messageId 重叠用例在
step 3 即被过滤为 filteredHydratedEvents=[],无法验证 step 4 mergeEvents
入参顺序对 key 冲突归并的影响。

补一条 RUN_STARTED 用例:realtime / hydrated 同 threadId/runId/timestamp
(eventKey 字节级一致)→ 用对象引用断言保留的是 realtime 版本,作为参数
顺序交换的最直接证据。该用例在交换前会失败、交换后通过,形成有效回归网。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 消除 LLM 思考独白溢出 / 推理头常驻 / 刷新乱序残留 (ISSUE-040) (#433)

* fix(home-chat): 消除 LLM 思考独白溢出 / 推理头常驻 / 刷新乱序残留 (ISSUE-040);

- 过滤 ADK Part 中 thought=true 与 type=thinking|thought|reasoning 系列推理字段,避免 reasoning_content 溢出到 TEXT_MESSAGE_CONTENT;推理文本改路由为 ne.a2ui.thought 自定义事件保留可观测性。
- createStepFinishedEvent 同步透出 stepName,AdkMessageStreamNormalizer 持有 stepId→stepName 映射,根治 ag-ui v0.0.47 校验器 "Cannot send 'STEP_FINISHED' for step \"undefined\"" 中断 run 导致的推理头永驻 started 现象。
- conversation-tree fallback 段重建消息节点时优先复用 ledger 已有 sourceOrder,避免被推到 events 末尾破坏 compareLedgerEntriesByTime tiebreaker。
- session-hydration eventKey 全事件类型统一走 toFixed(3) 毫秒级时间戳,并为 STEP_STARTED/STEP_FINISHED 显式按 (threadId, runId, stepId) 作 key,覆盖 STEP_*/CUSTOM/STATE_*/RAW 在浮点抖动下的去重盲区。
- 新增 9 例单元回归覆盖 thought part 过滤 / STEP_FINISHED stepName / fallback sourceOrder / eventKey 浮点抖动;docs/issue.md 追加 ISSUE-040 全栈解析。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 消除 hydration sort 字典序污染 lifecycle 顺序导致的多消息刷新乱序 (ISSUE-040 Q3 长尾);

- hydrateSessionDetail 引入 WeakMap<BaseEvent, emitOrder>,sort tiebreaker 用 normalizer 推入顺序代替 eventKey().localeCompare,保留 TEXT_MESSAGE_* 三件套 START→CONTENT→END 与跨 messageId 的 turn 边界。
- mergeEvents 同步改为按首次出现位置记录 insertionOrder 作 tiebreaker,避免最后一步 mergeEvents([], normalizedEvents) 再把刚排好的事件按字典序乱序。
- 新增同 timestamp 下 lifecycle 顺序断言用例;多轮真实后端 events fixture 经修复链路输出 user(R1)→assistant(R1)→user(R2)→assistant(R2) 完全符合时间线。
- docs/issue.md 在 ISSUE-040 末尾追加 Q3 长尾闭环(H5 字典序污染根因与最小干预修复)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(home-chat): 强化 ISSUE-040 H3 fallback sourceOrder 回归用例;

- 旧用例与单 snapshot 单条消息时新旧公式恰巧同值,断言无差异,无法拦截 H3 退化;
- 新用例构造「snapshot 数组顺序 vs ledger 时间序」错位场景:让 sourceOrder 在两条消息间发生互换,对回滚 H3 修复有强差异断言(已本地反向核验:回滚 conversation-tree.ts 修复后断言失败)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(wiki-header): catalog 第一层提升为顶部 Header 导航 tabs (#434)

* feat(wiki-header): catalog 第一层提升为顶部 Header 导航 tabs;

将 publication catalog 的第一层 CONTAINER 节点(如 Harness-Engineering)
从左侧 Sidebar 迁移为顶部 Header tabs;第二层及以下保留于 Sidebar,整树向上提升一档。
设计参考 GitHub Docs / Stripe Docs / Docusaurus 的"顶 tabs + 左 sidebar 子树"模式。

主要变更:
- lib/wiki-api.ts 追加 findFirstDocumentSlug / findActiveTopLevelSlug / resolveSectionView
  纯函数,作为 Header tabs 与 Sidebar 切片的单一事实源。
- 新增 WikiHeader Server Component(仅 <Link>,SSG 友好):渲染品牌 + 水平 tabs;
  CONTAINER tab 跳转 DFS 首个后代 DOCUMENT;无文档则禁用 span。
- WikiLayoutShell 增加 header? prop,渲染于 .wiki-layout 之外作为兄弟节点,
  避免触动既有 3 列 Grid 与 data-toc 三态。
- /{pubSlug} 与 /{pubSlug}/{...entrySlug} 两条路由共用 resolveSectionView 派生视图:
  pub 根页默认激活首项;entry 页按 slug 反查所属一级。
- globals.css 引入 --wiki-header-height 并把 sidebar / toc-aside 的 sticky top
  改为 var 引用,确保滚动时 Header 常驻不挡 sidebar。
- 新增 wiki-section-view.test.ts 12 用例覆盖空树 / 单 / 多 / 深路径 / DOCUMENT-only
  / 无后代 DOCUMENT 等边界。

回归保障:home / 不变;既有 WikiNavTree / WikiToc 测试 API 未变;47/47 单测全绿。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(wiki-header): Header 缺失时 sidebar/toc 不再残留偏移;

通过 data-header 属性标记 Header 是否存在,CSS 侧条件生效
--wiki-header-height 偏移,避免空导航树时出现 56px 空白间隙。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* refactor(config): 废弃 .env*,统一 YAML 三级配置(local > user > default) (#436)

* refactor(config): 废弃 .env* 加载链路,引入 config.local.yaml 统一 YAML 三级配置;

- 移除 10 个 Python 配置模块中的 env_file / _get_env_files 逻辑
- yaml_loader 新增 config.local.yaml 作为最高优先级 YAML 来源
- config.default.yaml 合并 .env 全部非机密差异值(含 OAuth 端口 6600→3292 校正)
- 新增 3 例 config.local.yaml 优先级测试

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(config): 同步 .env 废弃后的文档与 CHANGELOG;

- development.md / sso.md / framework.md / user-guide.md / zh-CN/README.md 中 .env 引用替换为 config.local.yaml
- CHANGELOG 新增 ISSUE-041 变更记录
- docs/issue.md 新增 ISSUE-041 经验沉淀
- .gitignore 新增 apps/negentropy/config.local.yaml 排除规则

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(config): 放宽 .gitignore 中 config.local.yaml 匹配规则,覆盖任意 cwd 场景;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041) (#435)

* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041);

- 新增 isSyntheticRunId 共享识别函数(覆盖 runId 缺失 / DEFAULT_RUN_ID / runId === threadId 三类合成回退标记),三层 dedup 一致放宽:
  1. message-ledger.ts::isSemanticEquivalentEntry:runId 不等时若任一侧 synthetic 则放行,threadId + role + 内容前缀 + origin 多元仍是必要约束;
  2. conversation-tree.ts fallback 段 runMatches:识别合成 runId 兼容分支,避免同内容 fallback message 被强制重建为重复节点;
  3. conversation-tree.ts collapseDefaultTurnDuplicates → collapseSyntheticTurnDuplicates:扩展为识别 runId === threadId 的合成 turn;时间窗判定改为 per-child timestamp vs concrete turn timeRange,多轮场景下不再误放过期 concrete turn。
- session-hydration.ts::fallbackRunId 注释 ISSUE-041 契约(保留兜底防御,等 Phase 2 后端代理层注入 runId 后再渐进移除)。
- 新增 16 例自动化回归(含 1 例反向回滚断言):
  · message-ledger A1-A5 + isSyntheticRunId 单元 + 端到端 ledger merge(共 7 例);
  · conversation-tree C1/C2/C3/C5 + D4 反向回滚(共 5 例);
  · session-hydration D1/D1+/D2/D3 端到端(共 4 例)。
- docs/issue.md 追加 ISSUE-041 全栈解析(含 refresh 自愈非对称的根因证据、多轮二阶恶化、Phase 2-4 路线图、诊断抓手与同类问题影响),闭环 ISSUE-040 Q3 长尾自识别。

回归状态:482 测试全绿 + tsc 0 错误;浏览器实机 5 场景 × 3 次验证清单见 .context/issue-041/validation-protocol.md,待用户已登录态 Chrome 桥接就绪后执行。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(rfcs): 新增 Phase 3 / Phase 4 架构 RFC 草稿(ISSUE-041 后续路线图);

- docs/rfcs/0001-conversation-architecture-refactor.md:Phase 3 架构重塑 RFC(Codex Thread→Turn→Item 数据模型 / 6 层去重金字塔精简到 3 层 / 抽象 utils/dedup/ + config/projection-thresholds.ts / 投影缓存 / 8 sub-PR 渐进迁移路线 / 兼容性回归与风险评估)。
- docs/rfcs/0002-ui-interaction-enhancements.md:Phase 4 UI 交互能力 backlog(Reasoning Panel + Sub-Agent 嵌套 / 工具进度 + 中断审批 / Conversation Branching + Timeline 增强;按用户优先级 1/2/3 分组,附实施依赖图与 Acceptance Criteria)。

均为 Draft 状态,待团队评审通过后启动多 PR 渐进迁移。本 commit 仅文档先行,不动代码。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 增强 synthetic turn 折叠相似度判定与时间窗整体吸收 (ISSUE-041);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 双层防御消除跨 runId 三气泡——泛化 turn 折叠 + 跨 block 去重 (ISSUE-041);

将 collapseSyntheticTurnDuplicates 泛化为 collapseOverlappingTurns:按 threadId 分组,
对 synthetic turn 与同组 concrete turn 时间重叠+内容覆盖的进行折叠(双 concrete turn
保留以防误折叠合法多 run);新增 chat-display 层 dedupeAdjacentAssistantBlocks
作为安全网,对时间窗内内容高度相似的相邻 assistant-reply block 保留更完整的一个。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(test): 补充 message-ledger 测试 fixture 缺失的 id 字段 (ISSUE-041)

tsconfig.vitest.json 类型检查报 TS2741:baseRealtime 对象缺少
MessageLedgerEntry 必需的 id 属性。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(chat-display): 修复跨 block 去重时间窗单位错误 + 消除 bigramJaccard 重复实现 (ISSUE-041);

- CROSS_BLOCK_TIME_WINDOW_MS=120000 误将毫秒值与秒级时间戳比较,实际窗口约 33 小时
  而非预期的 2 分钟;改为 CROSS_BLOCK_TIME_WINDOW_SEC=120(秒)
- 移除 chat-display.ts 私有的 computeCharBigrams / bigramJaccard,统一从 message.ts
  导入 bigramJaccardSimilarity,避免两处实现分叉

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041) (#437)

* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041);

- 新增 isSyntheticRunId 共享识别函数(覆盖 runId 缺失 / DEFAULT_RUN_ID / runId === threadId 三类合成回退标记),三层 dedup 一致放宽:
  1. message-ledger.ts::isSemanticEquivalentEntry:runId 不等时若任一侧 synthetic 则放行,threadId + role + 内容前缀 + origin 多元仍是必要约束;
  2. conversation-tree.ts fallback 段 runMatches:识别合成 runId 兼容分支,避免同内容 fallback message 被强制重建为重复节点;
  3. conversation-tree.ts collapseDefaultTurnDuplicates → collapseSyntheticTurnDuplicates:扩展为识别 runId === threadId 的合成 turn;时间窗判定改为 per-child timestamp vs concrete turn timeRange,多轮场景下不再误放过期 concrete turn。
- session-hydration.ts::fallbackRunId 注释 ISSUE-041 契约(保留兜底防御,等 Phase 2 后端代理层注入 runId 后再渐进移除)。
- 新增 16 例自动化回归(含 1 例反向回滚断言):
  · message-ledger A1-A5 + isSyntheticRunId 单元 + 端到端 ledger merge(共 7 例);
  · conversation-tree C1/C2/C3/C5 + D4 反向回滚(共 5 例);
  · session-hydration D1/D1+/D2/D3 端到端(共 4 例)。
- docs/issue.md 追加 ISSUE-041 全栈解析(含 refresh 自愈非对称的根因证据、多轮二阶恶化、Phase 2-4 路线图、诊断抓手与同类问题影响),闭环 ISSUE-040 Q3 长尾自识别。

回归状态:482 测试全绿 + tsc 0 错误;浏览器实机 5 场景 × 3 次验证清单见 .context/issue-041/validation-protocol.md,待用户已登录态 Chrome 桥接就绪后执行。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(rfcs): 新增 Phase 3 / Phase 4 架构 RFC 草稿(ISSUE-041 后续路线图);

- docs/rfcs/0001-conversation-architecture-refactor.md:Phase 3 架构重塑 RFC(Codex Thread→Turn→Item 数据模型 / 6 层去重金字塔精简到 3 层 / 抽象 utils/dedup/ + config/projection-thresholds.ts / 投影缓存 / 8 sub-PR 渐进迁移路线 / 兼容性回归与风险评估)。
- docs/rfcs/0002-ui-interaction-enhancements.md:Phase 4 UI 交互能力 backlog(Reasoning Panel + Sub-Agent 嵌套 / 工具进度 + 中断审批 / Conversation Branching + Timeline 增强;按用户优先级 1/2/3 分组,附实施依赖图与 Acceptance Criteria)。

均为 Draft 状态,待团队评审通过后启动多 PR 渐进迁移。本 commit 仅文档先行,不动代码。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 增强 synthetic turn 折叠相似度判定与时间窗整体吸收 (ISSUE-041);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 双层防御消除跨 runId 三气泡——泛化 turn 折叠 + 跨 block 去重 (ISSUE-041);

将 collapseSyntheticTurnDuplicates 泛化为 collapseOverlappingTurns:按 threadId 分组,
对 synthetic turn 与同组 concrete turn 时间重叠+内容覆盖的进行折叠(双 concrete turn
保留以防误折叠合法多 run);新增 chat-display 层 dedupeAdjacentAssistantBlocks
作为安全网,对时间窗内内容高度相似的相邻 assistant-reply block 保留更完整的一个。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(test): 补充 message-ledger 测试 fixture 缺失的 id 字段 (ISSUE-041)

tsconfig.vitest.json 类型检查报 TS2741:baseRealtime 对象缺少
MessageLedgerEntry 必需的 id 属性。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(chat-display): 修复跨 block 去重时间窗单位错误 + 消除 bigramJaccard 重复实现 (ISSUE-041);

- CROSS_BLOCK_TIME_WINDOW_MS=120000 误将毫秒值与秒级时间戳比较,实际窗口约 33 小时
  而非预期的 2 分钟;改为 CROSS_BLOCK_TIME_WINDOW_SEC=120(秒)
- 移除 chat-display.ts 私有的 computeCharBigrams / bigramJaccard,统一从 message.ts
  导入 bigramJaccardSimilarity,避免两处实现分叉

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(home-chat): 修复跨 runId 双气泡时间窗单位错误 + 消除 bigramJaccard 重复实现 (ISSUE-041);

fallback 路径从无条件移除改为内容覆盖检查——跨所有同 threadId keeper 逐 child
匹配,避免含独特历史内容的 synthetic turn 被误折叠。加强 C3 断言为
toHaveLength(2) + synthetictoBeDefined。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(conversation-tree): isSyntheticTurnNode 补充 "default" runId 识别对齐 isSyntheticRunId (ISSUE-041);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(ctl): 新增全套服务一键启停脚本 (#438)

* feat(ctl): 新增全套服务一键启停脚本 scripts/ctl.sh

支持 start/stop/restart/status/logs/build 子命令,覆盖依赖安装、
数据库迁移、前端构建、健康检查的完整生命周期。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(ctl): 修复 is_running 变量泄漏与并行 wait 退出码丢失;

- is_running() 中 pid_file 添加 local 声明,防止全局作用域污染
- 三处并行 wait 改为逐个检查退出码,任一子进程失败即报错中止

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(ctl): 修复健康检查不感知进程崩溃、路径逻辑重复与服务名校验缺失;

- wait_for_health 在 HTTP 轮询间隔中加入 is_running 检查,进程崩溃时立即返回失败
- is_running 改用 pid_file() 函数获取路径,消除硬编码重复
- cmd_logs 入口校验服务名是否属于 ALL_SERVICES,非法名称给出明确提示

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(ctl): 使用 exec 替代 eval 确保进程 PID 精确追踪与信号直达;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(kg): 知识图谱模块生产就绪改造 — 实体管理、混合检索、路径探索、统计面板 (#439)

* feat(kg): 知识图谱模块生产就绪改造 — 语料库级图谱、实体管理、混合检索、路径探索、统计面板

后端变更:
- 新增 GET /graph/entities 实体分页列表(类型筛选+名称搜索)
- 新增 GET /graph/entities/{id} 实体详情含出/入关系
- 新增 GET /graph/stats 图谱统计(实体数/类型分布/置信度/密度/度数)
- 重写 find_neighbors: 递归 CTE 在 kg_relations 上实现多跳遍历
- 重写 find_path: 递归 CTE BFS 在 kg_relations 上查找最短路径

前端变更:
- 重写 graph/page.tsx: 语料库选择器 + 构建/浏览全流程
- 新增 EntityListPanel: 表格视图+类型筛选+分页
- 新增 EntityDetailPanel: 实体详情+关系列表(出边/入边)
- 新增 SearchBar: 混合检索(语义+图结构)
- 新增 PathExplorer: 双实体选择+BFS路径查找
- 新增 NeighborExplorer: 1/2/3跳邻居展开
- 新增 GraphStatsPanel: 实体数/类型分布/置信度/密度/度数
- 新增 BuildHistoryList: 结构化构建历史卡片(状态徽章+统计+耗时)

文档变更:
- 扩展 user-guide.md §4.5 为完整知识图谱用户指引
- 更新 knowledge-graph.md §3 新增架构模式精炼(Cognee ECL/Graphiti 双时态)
- 更新 knowledge-graph.md §4 交付物清单

测试变更:
- 新增 test_graph_entity_service.py: 9 项单元测试覆盖实体列表/详情/Schema

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 修复知识图谱模块 CI 失败 — 类型错误、ID 前缀、测试 mock;

- 移除 NeighborExplorer 组件调用中不存在的 entityName prop(TS2322)
- 为 find_neighbors 返回的 GraphNode.id 补齐 entity: 前缀
- 重写 find_path 测试,mock session.execute 而非 find_neighbors

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 修复审查发现的 7 项问题 — 安全编码、状态管理、双向路径搜索;

- 路由 path params 加 encodeURIComponent 防路径遍历(3 个 route 文件)
- EntityDetailPanel: 用 loadedEntityId 派生 loading 状态,切换实体时正确展示加载态并清除旧数据
- EntityListPanel: 搜索输入 300ms 防抖,用 completedKey 派生 loading 状态
- GraphStatsPanel: 用 result 组合状态区分加载中/失败/成功
- NeighborExplorer: entityId 变更时重置 expanded/neighbors
- graph_repository find_path: 递归 CTE 增加反向遍历分支,与 find_neighbors 双向语义对齐

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 修复审查发现的遗留问题 — 常量提取、路径搜索、会话管理;

- 前端:提取 ENTITY_TYPE_COLORS 至 constants.ts,消除三处 TYPE_COLORS 残留引用(会导致运行时崩溃)
- 后端:修复 find_path 递归 CTE 中 path 追加错误(r.target_id → ps.target_id)
- 后端:get_stats 改为接收外部 db 会话,消除自建会话
- 后端:get_entity_detail 增加 corpus_id 可选过滤,增强数据隔离

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(memory): 记忆模块生产就绪化 — 巩固管线重构 + 事实提取 + 上下文集成 + 文档完善 (#440)

* feat(memory): 重构记忆巩固管线为三阶段智能架构并增强核心模块

- 重构 _simple_consolidate 为三阶段管线(分段→去重→存储),借鉴 Claude Code AutoDream 四阶段范式
- 新增 PatternFactExtractor 基于正则模式的对话事实自动提取(preference/profile/rule/custom)
- 新增 ContextAssembler 记忆上下文组装器,管理 token 预算分配(30%记忆/50%历史/20%系统)
- 新增 AsyncScheduler 应用层调度器回退,当 pg_cron 不可用时提供等效定时任务能力
- 增强 search_memory API 支持分页(limit/offset)和过滤(memory_type/date_from/date_to)
- 集成 ContextAssembler 到 perception.py 记忆搜索回退路径
- 新增 34 条单元测试覆盖事实提取和调度器(全部通过)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(memory): 补充工业框架对标分析与用户操作指南

- docs/memory.md §2.4 新增 Claude Code 记忆架构深度对标(AutoDream 四阶段整理、三重门控调度、四类型分类法、三层上下文压缩、漂移防御)
- docs/memory.md §2.5 新增 Agent Harness 设计模式对标(三层压缩管线、Skill 按需加载、Task Graph 持久化)
- docs/memory.md §2.6 新增 Negentropy 差异化定位总结表
- docs/user-guide.md §5.8-§5.12 新增记忆形成机制、保留分数解读、搜索最佳实践、自动化配置指南、故障排除

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 恢复巩固管线 metadata 中遗漏的 event_count 字段

三阶段管线重构后 metadata 字典遗漏了原有的 event_count 字段,
导致 test_memory_service_lifecycle 集成测试 KeyError 失败。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 修复 Code Review 反馈的 7 项问题

1. search_memory 的 memory_type/date_from/date_to/offset 过滤参数现在在 vector_search 和 ilike_search 中实际生效
2. context_assembler 的 lazy import 移至文件顶部,与同文件风格一致
3. _simple_consolidate docstring 从「三阶段」更正为「四阶段」(含事实提取)
4. api.py search_memories 的 total 字段添加 TODO 标记(需独立 COUNT 查询)
5. AsyncScheduler 失败时回退 last_run_at,允许尽快重试而非等完整 interval
6. PatternFactExtractor 三段重复遍历提取为 _match_patterns 辅助方法
7. _consolidate SQL 拼接改为参数化绑定 :lookback::interval,消除注入风险

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 修复 Code Review 反馈的 3 项问题

- offset 分页参数未透传到底层搜索方法,现已正确传递
- datetime.fromisoformat() 缺少校验,非法日期返回 400 而非 500
- AsyncScheduler 派发任务未被追踪,stop() 时一并取消在途任务

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 修复 Code Review 反馈的 2 项问题

- 巩固管线阶段 4 事实提取调用包裹 try/except,防止导入或工厂失败中断管线
- 搜索接口 total 字段改为 -1 标记"未知",避免分页客户端误读

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(memory): 记忆模块 Phase 2 — LLM 事实提取 + 摘要生成 + Token 精确计数 + 检索反馈闭环 (#442)

* feat(memory): 记忆模块 Phase 2 — LLM 事实提取 + 摘要生成 + 精确 Token 计数 + 检索反馈闭环

- TokenCounter: 基于 tiktoken cl100k_base 编码器精确计数,替代 LENGTH/4 粗略估算
- LLMFactExtractor: LLM 结构化输出事实提取,PatternFactExtractor 作为降级后备
- MemorySummarizer: LLM 生成结构化用户画像摘要,缓存至 memory_summaries 表(TTL 24h)
- SummaryService: memory_summaries 表 CRUD(upsert 语义)
- RetrievalTracker: 检索效果反馈闭环,记录检索事件 + 显式反馈 API
- ContextAssembler: 优先注入摘要,tiktoken 精确 token 计数
- 新增 Alembic migration 0013/0014(memory_summaries + memory_retrieval_logs)
- 新增 MemorySummary + MemoryRetrievalLog ORM 模型
- 11 条新增单元测试,62 条全部通过,零回归

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(memory): Phase 2 文档沉淀 — 两级提取策略 + 摘要巩固 + 精确计数 + 检索反馈 + 新增文献

- §4.2 扩展为两级事实提取策略说明(LLMFactExtractor + PatternFactExtractor)
- §5.4.1 新增摘要巩固策略(记忆再巩固理论 + 5 项工程对标)
- §6.3 更新 Token 估算为 tiktoken BPE 精确计数
- §6.5 新增检索效果反馈闭环(Rocchio + LTR + LongMemEval 评估维度)
- §15 新增 6 篇参考文献(Sennrich 2016, Sara 2015, Rocchio 1971, Burges 2005, Mem0, Letta)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 修复 LLM 事实提取 prompt 类型名不匹配 + 检索指标 SQL 聚合优化;

- prompt 模板中 "pref" 改为 "preference",与 _VALID_FACT_TYPES 验证器对齐,避免 LLM 输出被静默降级为 "custom"
- get_effectiveness_metrics 改用 SQL COUNT+CASE 聚合,避免将全量日志行加载到 Python 内存

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* refactor(memory): Review 反馈修复 — 检索日志可观测性 + query 透传 + 模型配置去重;

1. 检索追踪 except 从 silent pass 改为 logger.debug,使故障可诊断
2. _record_access 新增 query 参数并从所有调用点透传,消除空 query 问题
3. 提取 _resolve_model_config 为共享工具 engine/utils/model_config.py,
   LLMFactExtractor 和 MemorySummarizer 统一引用,消除 DRY 违规
4. 同步更新单元测试 mock 路径

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 修复图谱双写数据流断链 — 一等公民表对齐 (#441)

* fix(kg): 修复图谱双写数据流断链 — 一等公民表对齐

- create_relation() 新增写入 kg_relations 一等公民表,保留 JSONB 过渡兼容
- get_graph() 优先从 kg_entities + kg_relations 读取,空时回退 JSONB
- clear_graph() 增加 kg_entities/kg_relations 表清理
- build_graph() 完成后调用 KgEntityService.batch_sync_from_graph_build()
- 更新 test_graph_repository 适配新读写路径

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(kg): 新增 PageRank 实体重要性评分与 RRF 混合检索

- 新增 graph_algorithms 模块,基于 NetworkX 实现 PageRank (Brin & Page, 1998) 计算,
  结果持久化至 kg_entities.importance_score
- 混合检索支持 Reciprocal Rank Fusion (Cormack et al., SIGIR 2009) 模式,
  可通过 GraphQueryConfig.use_rrf / rrf_k 配置,向后兼容线性加权模式
- 图谱构建完成后自动触发 PageRank 计算
- 实体列表支持按重要性排序(sort_by=importance)
- 统计面板展示 Top 5 PageRank 实体
- 图谱可视化节点半径映射 PageRank 分数,突出重要实体

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(kg): 新增 Louvain 社区检测与图谱可视化增强

- 新增 compute_louvain() 算法,基于 NetworkX 内置 Louvain (Blondel et al., 2008)
  在无向投影图上运行社区检测,结果持久化至 kg_entities.community_id
- 图谱构建完成后自动触发 Louvain 计算(紧接 PageRank 之后)
- 统计面板新增社区分布(community_count + community_distribution)
- 实体列表和详情响应包含 community_id 字段
- 图谱可视化节点按社区着色(Tableau 10 色盲友好调色板)
- 统计面板展示 Top 8 社区分布柱状图
- 实体表格新增社区列,显示色块标识
- 显式声明 networkx>=3.0 依赖(此前为隐式运行时导入)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 新增 Alembic migration 0015 — 添加 importance_score 和 community_id 列

CI 集成测试失败根因:ORM 模型新增了 importance_score (PageRank) 和 community_id (Louvain)
列,但缺少对应的 Alembic migration,导致测试数据库 schema 不匹配。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(kg): 修复 Review 反馈的三个问题

1. RRF 搜索 graph_score 恒为 0 — 将 importance_score 写入 entity_data
2. PageRank/Louvain 逐条 UPDATE — 改为 VALUES CTE 批量更新
3. 一等公民表路径缺 app_name 过滤 — 文档明确 corpus 级去重设计意图

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(memory): Phase 2+ 增强 — 反馈闭环闭合 + Query-Aware 组装 + 近重复检测 + 测试覆盖 (#443)

* test(memory): Phase 2 组件测试覆盖 — TokenCounter / SummaryService / RetrievalTracker / MemorySummarizer;

新增 39 个单元测试用例,覆盖 Phase 2 四个核心组件:
- TokenCounter: 精确计数、空输入、幂等性、异步一致性、单调性(蜕变测试)
- SummaryService: upsert/get/delete CRUD 路径
- RetrievalTracker: 检索日志、引用标记、反馈记录、效果指标计算
- MemorySummarizer: 摘要生成、TTL 缓存命中/过期、LLM 失败降级、重试

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(memory): Phase 2+ 增强 — 反馈闭环闭合 + Query-Aware 组装 + 近重复检测 + 文档沉淀;

Gap 1 反馈闭环:
- _record_access 修复 user_id/app_name 透传(此前始终为空字符串)
- PostgresMemoryService 存储 _last_retrieval_log_id 供下游消费
- ContextAssembler 注入 mark_referenced 隐式反馈信号(RLHF[33])
- API 新增 POST /memory/retrieval/feedback 和 GET /memory/retrieval/metrics

Gap 2 Query-Aware:
- assemble() 新增 query/query_embedding 可选参数
- _call_get_context_window 传递 7 个参数(含 p_query, p_query_embedding)
- SQL 函数 NULL safe 退化:无 query 时保持纯 retention_score 排序
- 隐式反馈标记在上下文组装成功后触发

Gap 3 近重复检测:
- _is_duplicate 阈值从 0.9 降至 0.85(Henzinger[40])
- 新增 Jaccard 词重叠二次校验(0.80-0.85 区间,Broder[37])
- FactService 新增 merge_similar_facts() 语义去重方法

文档沉淀:
- docs/memory.md 权威源文件索引扩充 Phase 2 组件
- §15 追加 13 篇参考文献 [31]–[43]

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(memory): 修复 merge_similar_facts 过度删除 + retrieval_log_id 并发安全问题;

- merge_similar_facts: 锚点事实被删除后立即 break 内层循环,避免基于已删除 embedding 继续比对导致误删
- _record_access: 移除 _last_retrieval_log_id 实例属性,改为返回 log_id,消除共享可变状态的并发竞态
- ContextAssembler.assemble: memory_service 参数改为显式 retrieval_log_id,调用方直接传入

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(kg): Phase 3 生产就绪增强 — 增量构建 + 语义去重 + 管线健壮性 + 查询缓存 (#444)

* feat(kg): Phase 3 生产就绪增强 — 增量构建 + 语义去重 + 管线健壮性 + 查询缓存

Gap 3 [P1] 构建管线健壮性 (Nygard, 2018; Majors, 2022):
- Migration 0016: kg_build_runs 增加 progress_percent + warnings 列
- build_graph: 批处理循环进度上报、LLM 提取失败…
ThreeFish-AI added a commit that referenced this pull request May 19, 2026
…识管理统一入口(100 PRs / 843 文件) (#560) (#579)

* feat(agent-defs): 主 Agent 入库 + 按 DB 读 instruction + 模型选择回退 (#420)

* fix(agent-defs): 修复 Agent 加载路径 + 主 Agent 纳入 Interface Sync + 运行时按 DB 读 instruction;

- cli.py: --reload_agents 改用 Path(__file__) 推导的绝对路径,杜绝 cwd 依赖导致的「src/negentropy/negentropy」双重段错误;
- subagent_presets: 新增 NegentropyEngine root payload(adk_config.kind="root"),Sync 后 DB 出现主 Agent 行;
- sync API: 循环写入 config.kind,末尾调 invalidate_cache(prefix="subagent:") 批量失效;
- SubAgentResponse: 新增顶层 kind 字段(root/subagent),供前端置顶 + 徽章;
- model_resolver: 抽取 _load_subagent_row 共用单行查询,新增 resolve_subagent_instruction;
- _dynamic_instruction: 新增 InstructionProvider 工厂,root + 5 子 Agent 的 instruction 接入运行时 DB 读取;
- 测试: 更新 test_subagent_presets 覆盖 root payload + kind 断言;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-llm): 修复无 Session 时模型选择回退 + SubAgents 列表 Root 置顶徽章;

- home-body: 新增 pendingLlmRef,改写 handleSelectedLlmModelChange 与 Effect 1,
  使「无 session 选模型→建 session→自动发送」全流程保持选择不丢失;
- SubAgents page: 按 kind="root" 置顶排序,Sync 按钮文案从「Sync Negentropy 5」改为「Sync Negentropy」;
- SubAgentCard: Root Agent 显示 violet 色 Root 徽章;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(model-resolver): SubAgent 行缺失/未启用补回 60s TTL 负命中缓存;

回归点:重构 `_resolve_subagent_row` 时把空占位写入移到了 `loaded is None`
判断之后,导致禁用 Faculty 与未 Sync 环境下每次 LLM 请求都触发一次 DB 查询。
本次在 `loaded is None` 分支补 `_cache[cache_key] = ("", {"i": ""}, now)`,
让负命中同样落入 60s TTL,避免重复 DB 压力。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-llm): pending 模型选择仅对 startNewSession 新 id 消费;

回归点:Effect 1 的 pending 转移分支会在「首次进入既有 session」时触发,
把无 session 阶段的 pending 模型写入该 session 的 perThreadLlmRef,
并让 Effect 2 跳过 snapshot 初始化,导致服务器端记忆模型被静默替换。

修复方式:
- 新增 `pendingLlmTargetIdRef` 仅记录 startNewSession 返回的新 id;
- 通过 `startNewSessionWithLlmTarget` 包装内联调用与 `onNewSession` 两条路径;
- Effect 1 仅在 `sessionId === pendingLlmTargetIdRef.current` 时转移 pending,
  其余进入既有 session 的分支主动丢弃 pending,让 snapshot 正常生效。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(knowledge): 修复 KB Retrieve 全屏空白(前端聚合 rejection × 后端 hybrid/rrf 降级 × 502 上游错误码 × 诊断仪器化) (#421)

* fix(knowledge): 修复 Knowledge Base Retrieve 全屏空白(前端聚合 rejection + 后端 hybrid/rrf 降级 + 502 错误码 + 诊断日志);

双层 Bug 同因联修(详见 docs/issue.md ISSUE-026):
1. 前端 searchAcrossCorpora 旧实现以 Promise.allSettled 仅取 fulfilled,rejected 静默丢失,导致全部 Corpus 失败时返回 {count:0,items:[]} 走"成功路径"使 UI 空白且无任何提示——本次改为聚合三态(全成功/部分失败/全失败),SearchResults 类型扩展 errors[],handleRetrieve 对部分失败 toast.warning 透出原因;
2. 后端 service.search hybrid/rrf 旧实现未捕获 EmbeddingFailed,外部 Embedding 上游故障直接 500,丧失"keyword 仍可用"的优雅降级——本次 hybrid 失败回退 keyword-only、rrf 失败走与 not embedding_fn 等价的回退路径,semantic 仍传播以保留显式失败语义;
3. api.py _map_exception_to_http 拆分 EmbeddingFailed 分支映射到 502 Bad Gateway(保留 EMBEDDING_FAILED code),与 SearchError 自身错误的 500 区分,便于前端识别"上游修复后再试"语义;
4. embedding.py 调用 litellm 前后增加结构化诊断日志:api_base_host(脱敏 path/credentials 仅留 host)+ input_count + text_preview + kwargs_keys;失败附 upstream_response_text(沿异常链 __cause__/__context__ 提取 MaskedHTTPStatusError.text,已被 litellm 脱敏 URL,限长 500 字节);
5. 测试锁定:tests/unit_tests/knowledge/test_search_resilience.py 5 例(hybrid/rrf 降级 + semantic 传播 + EmbeddingFailed→502 + SearchError→500)+ tests/unit/knowledge/searchAcrossCorpora.test.ts 3 例(allSettled 三态);
6. docs/issue.md 追加 ISSUE-026,含后续防范(Promise.allSettled 必须聚合 rejection / vendor 失败必须 502 / hybrid 必须有降级路径 / vendor 调用必须 host+upstream_text 双信号)与同类问题影响清单。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(knowledge): searchAcrossCorpora 聚合保留 KnowledgeError code 并修正 _map_exception_to_http docstring;

Review #1(前端契约): SearchResultError 仅透 message 会丢弃 KnowledgeError.code(如 EMBEDDING_FAILED),削弱本次 502/500 拆分对前端"上游修复 vs 自身错误"的可分流价值——本次扩展 SearchResultError 增加可选 code,rejection instanceof KnowledgeError 时回填;全失败分支由 throw new Error 改为 throw new KnowledgeError(aggregatedCode, msg, {errors}),code 一致时透传原 code、混合时退化为 AGGREGATED_SEARCH_ERRORS,既保留分流能力又携带逐条失败明细;新增 1 例同 code 透传 + 1 例混合 code 退化的单测,全部 4 例通过。

Review #2(后端文档): api._map_exception_to_http docstring 仍只列 400/404/409/500,与新增 EmbeddingFailed→502 分支不一致;本次补 "502: 上游服务错误(vendor / Embedding 等外部依赖)" 一行,避免后续维护者按旧映射加分支。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(wiki-favicon): 修复 negentropy-wiki 站点 favicon.ico 单分辨率畸形导致浏览器回落默认地球图标; (#423)

- 根因:apps/negentropy-wiki/src/app/favicon.ico 是单分辨率畸形 ICO(file 输出 256x-1,高度字节 0xFF),且源图 logo.png 为非方形 800x798,导致 Chrome/Firefox/Safari 解析失败、tab 回落默认地球图标;
- 修复:用 Pillow 对 logo.png 做透明 padding 至 800x800 方形,再生成多分辨率 ICO(16/32/48/64/128/256 共六档)覆盖原文件;体积从 269KB 降至 118KB;
- 验证:file 输出 6 icons; pnpm build 后 .next/standalone 内 favicon route + body + meta 完整;pnpm start 后 curl /favicon.ico 返回 200 image/x-icon,HTML 自动注入 <link rel="icon">;
- 防范:docs/issue.md 追加 ISSUE-027,沉淀「ICO 必须方形 + 多分辨率」工程约束与 Pillow 流水线模板,禁止「原图直裹 ICO 头」反模式;
- 不动:layout.tsx / next.config.ts / start-production.mjs,保留 App Router metadata 自动注入路径,最小干预。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* feat(mcp-resources): 接入 Resource Templates 并贯通 PDF 图片到 Wiki Markdown (#422)

* feat(mcp-client): 接入 MCP Resource Templates 与同会话动态资源拉取;

新增 McpResourceTemplate 模型与 Alembic migration 0012,扩展 McpClientService 在
连接发现阶段并发调用 list_resource_templates(旧 server 不支持时静默兜底,不
阻断 tools 发现),新增 call_tool_and_resolve_resources:在同一 ClientSession 内
完成工具调用与所有 resource_link URI 的并发拉取(Semaphore 限流 4,return_exceptions
保证单条失败不击穿主流程)。这是接入 Negentropy Perceives 动态 FileResource
(perceives://pdf/<job_id>/<filename>)的协议层基石——动态实例的生命周期与工具
会话强绑定,必须在 session 关闭前完成 resources/read 才能避免事后失链。

Interface API 同步:load_mcp_server_tools 端点扩展为 capability 全量同步(tools
+ resource_templates,软删除已下线的 templates),LoadToolsResponse 新增
resource_templates 字段(向后兼容),新增 GET /mcp/servers/{id}/resource-templates
端点;list_mcp_servers 拆解为分段计数避免 JOIN 笛卡尔积;McpServerResponse 暴露
resource_template_count 给前端展示。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(perceives-resources): PDF 图片资源端到端贯通到 GCS 与 Wiki Markdown;

把 Perceives MCP 工具调用返回的 ResourceLink 接入既有提取流水线(Ingest 与
Re-Parse from GCS),让 PDF 图片资源在主仓 ↔ Perceives 之间通过 MCP 协议
完整贯通:

- 提取层(extraction.py):新增 _extract_resource_link_assets 把 ResourceLink
  与同会话 read_resource 拉取的 base64 配对为 ExtractionAsset;_call_tool_with_plan
  改用 resolve_resource_links=True 路径,确保动态 URI 不会因会话关闭失链;
  _build_success_result 接收 resolved_resources / resource_errors,按 "warn +
  占位" 容错策略合并 assets 并标记 partial_failure 不阻断主入库;新增
  _rewrite_markdown_image_links 在 Markdown 写入 GCS 之前把相对路径图片引用
  重写为 /api/documents/{doc_id}/assets/{filename},重写采用 capture group 偏移
  以避免 alt 文本含同名 src 时误替换。

- Knowledge API:新增 GET /knowledge/wiki/documents/{document_id}/assets/{filename}
  公开端点,filename 严格白名单 ^[A-Za-z0-9._-]+$ 与 180 字符上限;鉴权策略与
  既有 wiki entry content 端点对齐——仅放通至少被一条 WikiPublicationEntry
  引用的 document,避免持任意 doc_id 拖走未发布文档资产。

- 前端 MCP 卡片(negentropy-ui):新增 Resource Templates 折叠区与 ResourceDetailPanel,
  视觉与 Tools 区完全镜像;page.tsx 在 tools:load 响应中同步消费
  resource_templates 段,状态合并到 ServerWithTools;动态实例(带 job_id)
  按设计不入卡片。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(mcp-client): Resource Templates 同步加 capability flag,避免静默兜底误清空模板表;

`_discover_on_transport` 对 `list_resource_templates` 的所有异常都会静默兜底返回空列表(兼容旧 server 与瞬态错误),但 `load_mcp_server_tools` 会把空列表当作权威结果裁剪 stale 行,导致一次网络抖动或 server bug 即抹掉全部模板;同时与 tools 同步"只增量更新、不裁剪"的语义不对称。

- `McpConnectionResult` 新增 `resource_templates_listed: bool`,仅在 `list_resource_templates` 成功返回时为 True;
- `load_mcp_server_tools` 仅在该 flag 为 True(权威空列表)时才裁剪 stale 模板,未支持/错误场景保留既有 DB 行;
- 单元测试覆盖 flag 在权威空列表与异常兜底两种路径下的取值。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* test(mcp-card): 单测 server fixture 补 resource_template_count 修 UI Type Checks;

`McpServer` 类型新增的必填字段 `resource_template_count` 未同步到 `McpServerCard.test.tsx` 的 server 固件,导致 ui-quality / UI Type Checks 在 5 处 `<McpServerCard server={...}>` 调用上报 TS2741。

- 在 server 固件加 `resource_template_count: 0`,spread 派生用例自动获得新字段。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(knowledge): 查询时 honor Corpus 自配 embedding 模型,修复 query/index 模型不一致 (ISSUE-028) (#424)

search() 原直接使用实例化时锁定的 self._embedding_fn(全局默认 gemini/text-embedding-004),
未读 corpus.config.models.embedding_config_id;而 _attach_embeddings 索引侧已按 corpus pin 走
专属 fn。两侧不对称导致:用户在 Corpus Settings 已切到 openai/text-embedding-3-small(1536 维),
索引按 OpenAI 生成,查询仍走 Gemini 全局默认经 localhost:3392 翻译代理报 400。

修复:
- 新增 _resolve_embedding_fn(corpus_config) 助手,corpus pin 优先 → 退回 service 默认 fn;
- search() 入口加载 corpus_config + embedding_fn 本地变量,rrf/hybrid/semantic 三分支替换;
- ISSUE-026 keyword 兜底 + 502 映射 + 诊断日志原样保留,零回归;
- 新增 5 例单元测试覆盖 corpus pin 命中/落空/兜底/rrf/semantic 上抛,577 全绿。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* fix(agent-llm): 修复 Home Send 时 LLM 凭证未从 DB 读取导致 AuthenticationError (#425)

* fix(docs): 同步文档启动命令与 cli.py 修复,消除 Home Send 500 复发路径;

cli.py 的 agents_dir 已在 35204ff 从 src/negentropy 修正为 src,
但 README / docs 下 4 个文件 7 处仍写 --reload_agents src/negentropy,
用户照文档启动复现 ValueError: Agent not found 500。
统一替换为 uv run negentropy serve(SSOT),
追加 ISSUE-029(文档漂移)与 ISSUE-030(SubAgents root Agent 防回归)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(agent-llm): 修复 Home Send 时 LLM 凭证未从 DB 读取导致 AuthenticationError;

DynamicRootLiteLlm/DynamicSubagentLiteLlm 在 ContextVar 或 sub_agents.model
为空时直接返回 None,回退到构造时无 api_key 的硬编码实例,绕过了 DB 中
已配置的 vendor_configs 凭证。现在始终通过 resolve_llm_config() 从 DB
解析默认模型的完整凭证(含 api_key)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 修复长耗时回复双气泡 + 首条未格式化 (ISSUE-031); (#426)

ADK 仅持久化 partial=false 终态事件,realtime 与 hydration 在
同一逻辑消息上派出不同的 messageId(首个 partial id vs 终态 id)。
isSemanticEquivalentEntry 的 8s 时间窗在长耗时回复下硬拒绝,导致
ledger 双 entry → events 过滤失败 → conversation tree 双节点 →
UI 渲染双气泡(首条因 streaming-markdown 尾部判定走 raw text 分支)。

修复 (最小干预 + 正交分解):
- message-ledger.ts: 内容严格相等时跳过 8s 时间窗硬拒绝。
- conversation-tree.ts: assistant 已收尾节点在内容严格相等时
  也允许 findMatchingTextNodeId 命中复用,作为防御性收敛。
- 三层回归测试覆盖 ">8s 跨度 + messageId 不同 + 内容严格相等"。

UI 全量 70 文件 396 测试通过;typecheck/typecheck:test/eslint 零报错。
docs/issue.md 沉淀 ISSUE-031;CHANGELOG.md 同步条目。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* fix(home-chat): 修复 Home 对话 title 凭证缺失与 OTLP logs/metrics 404 双联缺陷 (#427)

* fix(home-chat): 修复 Home 对话 title 凭证缺失 + OTLP logs/metrics 404 双联缺陷;

(1) SessionSummarizer 同步 __init__ 在 60s 缓存 miss 时回退到无 api_key 硬编码默认,
导致 LiteLLM AuthenticationError;改为 async classmethod create() 经 resolve_llm_config()
从 DB 读取完整凭证(与 commit 8ce35d5 修复 DynamicRootLiteLlm 同 SoT),调用方
session_service._generate_title_for_session 切换为 await SessionSummarizer.create(),
对 resolver 返回 kwargs 做防御性浅拷贝避免与 60s 缓存层耦合。

(2) ADK 上游 _get_otel_exporters() 把 OTEL_EXPORTER_OTLP_ENDPOINT 视为 OTLP 三件套
总开关,无差别注册 OTLPSpanExporter / OTLPMetricExporter / OTLPLogExporter;后两者
对 Langfuse 不存在的 /v1/metrics、/v1/logs 上报触发 SPA 404 SSR 错误页(每次对话
反复输出大段 HTML)。bootstrap.py 新增 _install_noop_otel_logs_metrics_providers()
在 OTel env var 设置后立即抢注无 processor / 无 reader 的 SDK Logger/Meter Provider,
利用 OTel SDK Once-lock 让 ADK 后续 set_*_provider 静默 no-op,从而阻断 logs/metrics
上报;TracerProvider 链路与 OTEL_EXPORTER_OTLP_HEADERS 不动,traces 仍正常进入 Langfuse。

新增 tests/unit_tests/engine/test_summarization.py(3 例)+
tests/unit_tests/observability/test_otel_noop_providers.py(3 例,子进程隔离 OTel 全局
状态)锁定回归。CHANGELOG / docs/issue.md 沉淀 ISSUE-031(title 凭证缺失)与
ISSUE-032(OTLP logs/metrics 404)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* test(otel-noop): 移除 _sdk_config hasattr 兜底,让 SDK 私有属性变更显式触发回归;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* test(session-title): 修复 DummySummarizer 缺失 async create() 导致集成测试 AttributeError;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(bootstrap-otel): 消除 ADK Web 启动期 OTel Override Provider 双 WARNING (ISSUE-034); (#428)

将 ISSUE-033 的「抢占式 set_logger_provider/set_meter_provider」改为 patch
`google.adk.telemetry.setup._get_otel_exporters`,让其只返回 traces 的
span_processors,metric_readers/log_record_processors 永久置空。ADK
maybe_set_otel_providers 的 if 分支由此天然短路,set_*_provider 根本不被
调用,从源头消除 OTel SDK 的 "Overriding of current ... is not allowed"
WARNING;traces 链路、ADK ApiServerSpanExporter、TracingManager、LiteLLM
"otel" callback 行为完全不变。配套更新 3 个子进程隔离单测验证新语义,
并在 docs/issue.md 追加 ISSUE-034 完整记录。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* feat(e2e-auth): 浏览器验证协议落地 + Playwright 会话复用贯通 Google OAuth (#429)

* docs(browser-validation): 落地浏览器验证协议并补 ISSUE-034

- AGENTS.md(即 CLAUDE.md symlink)新增"Browser Validation Protocol"子节,
  约定登录态浏览器验证必须复用用户常用 Chrome 会话,禁止 sandbox 浏览器
  通过 Google 同意屏,明确凭证守则与三步连通性自检;
- 新建 docs/agents/browser-validation.md:含三种 MCP 浏览器工具能力对照、
  Mermaid 选型决策图、storageState 工作时序、风控应对、IEEE 引用;
  实测附注 chrome-devtools MCP 在 macOS 默认即可复用用户主 profile 登录态;
- docs/issue.md 追加 ISSUE-034,记录 sandbox 浏览器走 Google OAuth 被拦
  的表因/根因/处理方式/防范,便于跨上下文复用。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* test(e2e-auth): Playwright 会话复用以贯通 Google OAuth E2E

- playwright.config.ts 在 PLAYWRIGHT_AUTH=1 时启用两个项目:
  * setup(headless: false,匹配 *.setup.ts),让用户在弹出窗手动登录;
  * chromium-authenticated(dependencies: ['setup']),使用 storageState
    复用一次性人工登录的会话;
  支持 PLAYWRIGHT_STORAGE_STATE 与 PLAYWRIGHT_USER_DATA_DIR 覆盖默认;
  现有 chromium project 加 testIgnore 排除 .setup.ts,CI/默认行为零变;
- 新增 tests/e2e/auth.setup.ts:打开 /auth/google/login,5 分钟内允许
  用户在 Google 同意屏中手动完成登录,回跳后断言 /api/auth/me 2xx,
  写入 storageState;
- .gitignore 追加 apps/negentropy-ui/.auth/ 与 .userdata/,
  防止会话凭证随分支推送外泄。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(e2e-auth): 修复 OAuth setup 早退与 authed spec 双跑;

- auth.setup.ts: waitForURL 谓词追加 host 约束,避免在跳往 accounts.google.com
  瞬间因 pathname 已离开 /auth/google 而误判完成,导致 /api/auth/me 在用户登录前
  失败、storageState 永不写出。
- playwright.config.ts: 基础 chromium project 的 testIgnore 追加
  /.*\.authed\.spec\.ts$/,防止 PLAYWRIGHT_AUTH=1 时同一份认证 spec 在
  chromium-authenticated 与 chromium 中各跑一次(后者无 storageState 必失败)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 修复 Home 双气泡复发与 LLM 模型未 Send 即刷新丢失 (ISSUE-032/033); (#430)

ISSUE-032 (双气泡复发,与 ISSUE-031 正交):
- 根因:root agent prompt 主动导航 + log_activity tool 让 ADK 走双轮 LLM 调用,
  两轮各自带独立 messageId 走完整 TEXT_MESSAGE_* 三件套,UI 在同一
  assistant-reply bubble 内并列渲染两段近重复文本。
- 修复:utils/chat-display.ts::dedupeRedundantTextSegments 在
  buildAssistantReplyBlock 出口对同一 reply 内的 text segment 做字符二元组
  Jaccard 相似度计算,相似度 ≥ 0.5 且双方长度 ≥ 30 时丢弃前段、保留信息更
  完备的最终段。tool-group / reasoning / error 顺序不动。
- assistant-reply.message.content 联动重组,复制时也拿到折叠后的内容。

ISSUE-033 (LLM 模型未 Send 即刷新丢失):
- 根因:后端事实源 session.state.selected_llm_model 仅在 /run_sse 时随
  state_delta 写入,未 Send 时不更新;前端 perThreadLlmRef 是 useRef
  刷新即丢;snapshotForDisplay 也无值,回退到 default。
- 修复:app/home-body.tsx 顶部新增 readPersistedLlmModel /
  writePersistedLlmModel (typeof window 守卫 + try/catch SSR 安全);
  handleSelectedLlmModelChange 即时落盘到 localStorage;Effect 1 优先
  从 localStorage 还原;Effect 2 命中 snapshot 时同步回写 localStorage,
  让「后端 state ↔ localStorage」互为镜像。既有 forwardedProps.selected_llm_model
  在 Send 时仍写后端 state,跨设备一致性最终收敛。

测试:
- 新增 2 例 chat-display.test.ts 用例:折叠近重复段 + 差异度大不被折叠
- UI 全量 70 文件 398 测试通过;typecheck/typecheck:test/eslint 零报错

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)

* fix(bootstrap-otel): 消除被丢弃 PeriodicExportingMetricReader 守护线程的周期 WARNING (ISSUE-038) (#431)

* fix(bootstrap-otel): 消除被丢弃 PeriodicExportingMetricReader 守护线程的周期 WARNING (ISSUE-038);

ISSUE-034 的 patch 调用 original() 后再丢弃 metric_readers /
log_record_processors,但上游 _get_otel_exporters 已构造
PeriodicExportingMetricReader 并启动 60s 守护线程——reader 未注册
到 MeterProvider 导致每 tick 触发 "Cannot call collect on a
MetricReader ..." WARNING。改为绕过 original(),直接复用
_get_otel_span_exporter() 仅构造 traces span processor,根源
避免 OTLP metrics/logs exporter 被实例化。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* docs(bootstrap-otel): 修正 _disable_adk_otel_logs_metrics_exporters docstring 中的过期 hooks 引用;

旧 docstring 沿用重构前 `hooks = original()` 的中间变量术语,但新实现已不再调用 `original()`,函数体内也没有 `hooks` 绑定。
更新指引为「恢复 _get_otel_exporters 原函数闭包」或「直接构造完整 OTelHooks」,避免误导后续维护者寻找已不存在的对象。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 修复 Home 双气泡盲区与刷新后消息乱序 (ISSUE-039) (#432)

* fix(home-chat): 修复 Home 双气泡盲区与刷新后消息乱序 (ISSUE-038);

- chat-display: dedupeRedundantTextSegments 增加四层判定(精确匹配 / 严格前缀 / 等价内容 / Jaccard),覆盖 ADK 双轮 LLM 短回复(如 "Pong!")的双气泡盲区。
- session-hydration: mergeEventsWithRealtimePriority 交换参数顺序,让 realtime 事件覆盖 hydrated;TEXT_MESSAGE_CONTENT 的 eventKey 时间戳改用 toFixed(3) 消除浮点抖动导致的同一事件重复保留。
- message-ledger: MessageLedgerEntry 新增可选 sourceOrder 作 createdAt 相同时的稳定 tiebreaker,替代 UUID localeCompare 的随机字典序;抽出 compareLedgerEntriesByTime 复用,类型保持向后兼容(缺省回退 Number.MAX_SAFE_INTEGER)。
- 新增 5 项单元测试覆盖:短回复精确匹配、前缀含尾部追加、Jaccard 长文本、eventKey 浮点稳定、sourceOrder 稳定排序;docs/issue.md 增补 ISSUE-038 摘要。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* test(home-chat): 补 mergeEventsWithRealtimePriority 生命周期事件覆盖回归用例;

针对 ISSUE-039 第 3 项修复(mergeEventsWithRealtimePriority 参数顺序交换)
原有 RUN_STARTED 类生命周期事件用例缺位——之前的 messageId 重叠用例在
step 3 即被过滤为 filteredHydratedEvents=[],无法验证 step 4 mergeEvents
入参顺序对 key 冲突归并的影响。

补一条 RUN_STARTED 用例:realtime / hydrated 同 threadId/runId/timestamp
(eventKey 字节级一致)→ 用对象引用断言保留的是 realtime 版本,作为参数
顺序交换的最直接证据。该用例在交换前会失败、交换后通过,形成有效回归网。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 消除 LLM 思考独白溢出 / 推理头常驻 / 刷新乱序残留 (ISSUE-040) (#433)

* fix(home-chat): 消除 LLM 思考独白溢出 / 推理头常驻 / 刷新乱序残留 (ISSUE-040);

- 过滤 ADK Part 中 thought=true 与 type=thinking|thought|reasoning 系列推理字段,避免 reasoning_content 溢出到 TEXT_MESSAGE_CONTENT;推理文本改路由为 ne.a2ui.thought 自定义事件保留可观测性。
- createStepFinishedEvent 同步透出 stepName,AdkMessageStreamNormalizer 持有 stepId→stepName 映射,根治 ag-ui v0.0.47 校验器 "Cannot send 'STEP_FINISHED' for step \"undefined\"" 中断 run 导致的推理头永驻 started 现象。
- conversation-tree fallback 段重建消息节点时优先复用 ledger 已有 sourceOrder,避免被推到 events 末尾破坏 compareLedgerEntriesByTime tiebreaker。
- session-hydration eventKey 全事件类型统一走 toFixed(3) 毫秒级时间戳,并为 STEP_STARTED/STEP_FINISHED 显式按 (threadId, runId, stepId) 作 key,覆盖 STEP_*/CUSTOM/STATE_*/RAW 在浮点抖动下的去重盲区。
- 新增 9 例单元回归覆盖 thought part 过滤 / STEP_FINISHED stepName / fallback sourceOrder / eventKey 浮点抖动;docs/issue.md 追加 ISSUE-040 全栈解析。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 消除 hydration sort 字典序污染 lifecycle 顺序导致的多消息刷新乱序 (ISSUE-040 Q3 长尾);

- hydrateSessionDetail 引入 WeakMap<BaseEvent, emitOrder>,sort tiebreaker 用 normalizer 推入顺序代替 eventKey().localeCompare,保留 TEXT_MESSAGE_* 三件套 START→CONTENT→END 与跨 messageId 的 turn 边界。
- mergeEvents 同步改为按首次出现位置记录 insertionOrder 作 tiebreaker,避免最后一步 mergeEvents([], normalizedEvents) 再把刚排好的事件按字典序乱序。
- 新增同 timestamp 下 lifecycle 顺序断言用例;多轮真实后端 events fixture 经修复链路输出 user(R1)→assistant(R1)→user(R2)→assistant(R2) 完全符合时间线。
- docs/issue.md 在 ISSUE-040 末尾追加 Q3 长尾闭环(H5 字典序污染根因与最小干预修复)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* test(home-chat): 强化 ISSUE-040 H3 fallback sourceOrder 回归用例;

- 旧用例与单 snapshot 单条消息时新旧公式恰巧同值,断言无差异,无法拦截 H3 退化;
- 新用例构造「snapshot 数组顺序 vs ledger 时间序」错位场景:让 sourceOrder 在两条消息间发生互换,对回滚 H3 修复有强差异断言(已本地反向核验:回滚 conversation-tree.ts 修复后断言失败)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(wiki-header): catalog 第一层提升为顶部 Header 导航 tabs (#434)

* feat(wiki-header): catalog 第一层提升为顶部 Header 导航 tabs;

将 publication catalog 的第一层 CONTAINER 节点(如 Harness-Engineering)
从左侧 Sidebar 迁移为顶部 Header tabs;第二层及以下保留于 Sidebar,整树向上提升一档。
设计参考 GitHub Docs / Stripe Docs / Docusaurus 的"顶 tabs + 左 sidebar 子树"模式。

主要变更:
- lib/wiki-api.ts 追加 findFirstDocumentSlug / findActiveTopLevelSlug / resolveSectionView
  纯函数,作为 Header tabs 与 Sidebar 切片的单一事实源。
- 新增 WikiHeader Server Component(仅 <Link>,SSG 友好):渲染品牌 + 水平 tabs;
  CONTAINER tab 跳转 DFS 首个后代 DOCUMENT;无文档则禁用 span。
- WikiLayoutShell 增加 header? prop,渲染于 .wiki-layout 之外作为兄弟节点,
  避免触动既有 3 列 Grid 与 data-toc 三态。
- /{pubSlug} 与 /{pubSlug}/{...entrySlug} 两条路由共用 resolveSectionView 派生视图:
  pub 根页默认激活首项;entry 页按 slug 反查所属一级。
- globals.css 引入 --wiki-header-height 并把 sidebar / toc-aside 的 sticky top
  改为 var 引用,确保滚动时 Header 常驻不挡 sidebar。
- 新增 wiki-section-view.test.ts 12 用例覆盖空树 / 单 / 多 / 深路径 / DOCUMENT-only
  / 无后代 DOCUMENT 等边界。

回归保障:home / 不变;既有 WikiNavTree / WikiToc 测试 API 未变;47/47 单测全绿。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(wiki-header): Header 缺失时 sidebar/toc 不再残留偏移;

通过 data-header 属性标记 Header 是否存在,CSS 侧条件生效
--wiki-header-height 偏移,避免空导航树时出现 56px 空白间隙。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* refactor(config): 废弃 .env*,统一 YAML 三级配置(local > user > default) (#436)

* refactor(config): 废弃 .env* 加载链路,引入 config.local.yaml 统一 YAML 三级配置;

- 移除 10 个 Python 配置模块中的 env_file / _get_env_files 逻辑
- yaml_loader 新增 config.local.yaml 作为最高优先级 YAML 来源
- config.default.yaml 合并 .env 全部非机密差异值(含 OAuth 端口 6600→3292 校正)
- 新增 3 例 config.local.yaml 优先级测试

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* docs(config): 同步 .env 废弃后的文档与 CHANGELOG;

- development.md / sso.md / framework.md / user-guide.md / zh-CN/README.md 中 .env 引用替换为 config.local.yaml
- CHANGELOG 新增 ISSUE-041 变更记录
- docs/issue.md 新增 ISSUE-041 经验沉淀
- .gitignore 新增 apps/negentropy/config.local.yaml 排除规则

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(config): 放宽 .gitignore 中 config.local.yaml 匹配规则,覆盖任意 cwd 场景;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041) (#435)

* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041);

- 新增 isSyntheticRunId 共享识别函数(覆盖 runId 缺失 / DEFAULT_RUN_ID / runId === threadId 三类合成回退标记),三层 dedup 一致放宽:
  1. message-ledger.ts::isSemanticEquivalentEntry:runId 不等时若任一侧 synthetic 则放行,threadId + role + 内容前缀 + origin 多元仍是必要约束;
  2. conversation-tree.ts fallback 段 runMatches:识别合成 runId 兼容分支,避免同内容 fallback message 被强制重建为重复节点;
  3. conversation-tree.ts collapseDefaultTurnDuplicates → collapseSyntheticTurnDuplicates:扩展为识别 runId === threadId 的合成 turn;时间窗判定改为 per-child timestamp vs concrete turn timeRange,多轮场景下不再误放过期 concrete turn。
- session-hydration.ts::fallbackRunId 注释 ISSUE-041 契约(保留兜底防御,等 Phase 2 后端代理层注入 runId 后再渐进移除)。
- 新增 16 例自动化回归(含 1 例反向回滚断言):
  · message-ledger A1-A5 + isSyntheticRunId 单元 + 端到端 ledger merge(共 7 例);
  · conversation-tree C1/C2/C3/C5 + D4 反向回滚(共 5 例);
  · session-hydration D1/D1+/D2/D3 端到端(共 4 例)。
- docs/issue.md 追加 ISSUE-041 全栈解析(含 refresh 自愈非对称的根因证据、多轮二阶恶化、Phase 2-4 路线图、诊断抓手与同类问题影响),闭环 ISSUE-040 Q3 长尾自识别。

回归状态:482 测试全绿 + tsc 0 错误;浏览器实机 5 场景 × 3 次验证清单见 .context/issue-041/validation-protocol.md,待用户已登录态 Chrome 桥接就绪后执行。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* docs(rfcs): 新增 Phase 3 / Phase 4 架构 RFC 草稿(ISSUE-041 后续路线图);

- docs/rfcs/0001-conversation-architecture-refactor.md:Phase 3 架构重塑 RFC(Codex Thread→Turn→Item 数据模型 / 6 层去重金字塔精简到 3 层 / 抽象 utils/dedup/ + config/projection-thresholds.ts / 投影缓存 / 8 sub-PR 渐进迁移路线 / 兼容性回归与风险评估)。
- docs/rfcs/0002-ui-interaction-enhancements.md:Phase 4 UI 交互能力 backlog(Reasoning Panel + Sub-Agent 嵌套 / 工具进度 + 中断审批 / Conversation Branching + Timeline 增强;按用户优先级 1/2/3 分组,附实施依赖图与 Acceptance Criteria)。

均为 Draft 状态,待团队评审通过后启动多 PR 渐进迁移。本 commit 仅文档先行,不动代码。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 增强 synthetic turn 折叠相似度判定与时间窗整体吸收 (ISSUE-041);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 双层防御消除跨 runId 三气泡——泛化 turn 折叠 + 跨 block 去重 (ISSUE-041);

将 collapseSyntheticTurnDuplicates 泛化为 collapseOverlappingTurns:按 threadId 分组,
对 synthetic turn 与同组 concrete turn 时间重叠+内容覆盖的进行折叠(双 concrete turn
保留以防误折叠合法多 run);新增 chat-display 层 dedupeAdjacentAssistantBlocks
作为安全网,对时间窗内内容高度相似的相邻 assistant-reply block 保留更完整的一个。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(test): 补充 message-ledger 测试 fixture 缺失的 id 字段 (ISSUE-041)

tsconfig.vitest.json 类型检查报 TS2741:baseRealtime 对象缺少
MessageLedgerEntry 必需的 id 属性。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(chat-display): 修复跨 block 去重时间窗单位错误 + 消除 bigramJaccard 重复实现 (ISSUE-041);

- CROSS_BLOCK_TIME_WINDOW_MS=120000 误将毫秒值与秒级时间戳比较,实际窗口约 33 小时
  而非预期的 2 分钟;改为 CROSS_BLOCK_TIME_WINDOW_SEC=120(秒)
- 移除 chat-display.ts 私有的 computeCharBigrams / bigramJaccard,统一从 message.ts
  导入 bigramJaccardSimilarity,避免两处实现分叉

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041) (#437)

* fix(home-chat): 修复 realtime + hydration 跨 runId 双气泡复发 (ISSUE-041);

- 新增 isSyntheticRunId 共享识别函数(覆盖 runId 缺失 / DEFAULT_RUN_ID / runId === threadId 三类合成回退标记),三层 dedup 一致放宽:
  1. message-ledger.ts::isSemanticEquivalentEntry:runId 不等时若任一侧 synthetic 则放行,threadId + role + 内容前缀 + origin 多元仍是必要约束;
  2. conversation-tree.ts fallback 段 runMatches:识别合成 runId 兼容分支,避免同内容 fallback message 被强制重建为重复节点;
  3. conversation-tree.ts collapseDefaultTurnDuplicates → collapseSyntheticTurnDuplicates:扩展为识别 runId === threadId 的合成 turn;时间窗判定改为 per-child timestamp vs concrete turn timeRange,多轮场景下不再误放过期 concrete turn。
- session-hydration.ts::fallbackRunId 注释 ISSUE-041 契约(保留兜底防御,等 Phase 2 后端代理层注入 runId 后再渐进移除)。
- 新增 16 例自动化回归(含 1 例反向回滚断言):
  · message-ledger A1-A5 + isSyntheticRunId 单元 + 端到端 ledger merge(共 7 例);
  · conversation-tree C1/C2/C3/C5 + D4 反向回滚(共 5 例);
  · session-hydration D1/D1+/D2/D3 端到端(共 4 例)。
- docs/issue.md 追加 ISSUE-041 全栈解析(含 refresh 自愈非对称的根因证据、多轮二阶恶化、Phase 2-4 路线图、诊断抓手与同类问题影响),闭环 ISSUE-040 Q3 长尾自识别。

回归状态:482 测试全绿 + tsc 0 错误;浏览器实机 5 场景 × 3 次验证清单见 .context/issue-041/validation-protocol.md,待用户已登录态 Chrome 桥接就绪后执行。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* docs(rfcs): 新增 Phase 3 / Phase 4 架构 RFC 草稿(ISSUE-041 后续路线图);

- docs/rfcs/0001-conversation-architecture-refactor.md:Phase 3 架构重塑 RFC(Codex Thread→Turn→Item 数据模型 / 6 层去重金字塔精简到 3 层 / 抽象 utils/dedup/ + config/projection-thresholds.ts / 投影缓存 / 8 sub-PR 渐进迁移路线 / 兼容性回归与风险评估)。
- docs/rfcs/0002-ui-interaction-enhancements.md:Phase 4 UI 交互能力 backlog(Reasoning Panel + Sub-Agent 嵌套 / 工具进度 + 中断审批 / Conversation Branching + Timeline 增强;按用户优先级 1/2/3 分组,附实施依赖图与 Acceptance Criteria)。

均为 Draft 状态,待团队评审通过后启动多 PR 渐进迁移。本 commit 仅文档先行,不动代码。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 增强 synthetic turn 折叠相似度判定与时间窗整体吸收 (ISSUE-041);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 双层防御消除跨 runId 三气泡——泛化 turn 折叠 + 跨 block 去重 (ISSUE-041);

将 collapseSyntheticTurnDuplicates 泛化为 collapseOverlappingTurns:按 threadId 分组,
对 synthetic turn 与同组 concrete turn 时间重叠+内容覆盖的进行折叠(双 concrete turn
保留以防误折叠合法多 run);新增 chat-display 层 dedupeAdjacentAssistantBlocks
作为安全网,对时间窗内内容高度相似的相邻 assistant-reply block 保留更完整的一个。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(test): 补充 message-ledger 测试 fixture 缺失的 id 字段 (ISSUE-041)

tsconfig.vitest.json 类型检查报 TS2741:baseRealtime 对象缺少
MessageLedgerEntry 必需的 id 属性。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(chat-display): 修复跨 block 去重时间窗单位错误 + 消除 bigramJaccard 重复实现 (ISSUE-041);

- CROSS_BLOCK_TIME_WINDOW_MS=120000 误将毫秒值与秒级时间戳比较,实际窗口约 33 小时
  而非预期的 2 分钟;改为 CROSS_BLOCK_TIME_WINDOW_SEC=120(秒)
- 移除 chat-display.ts 私有的 computeCharBigrams / bigramJaccard,统一从 message.ts
  导入 bigramJaccardSimilarity,避免两处实现分叉

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(home-chat): 修复跨 runId 双气泡时间窗单位错误 + 消除 bigramJaccard 重复实现 (ISSUE-041);

fallback 路径从无条件移除改为内容覆盖检查——跨所有同 threadId keeper 逐 child
匹配,避免含独特历史内容的 synthetic turn 被误折叠。加强 C3 断言为
toHaveLength(2) + synthetictoBeDefined。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(conversation-tree): isSyntheticTurnNode 补充 "default" runId 识别对齐 isSyntheticRunId (ISSUE-041);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(ctl): 新增全套服务一键启停脚本 (#438)

* feat(ctl): 新增全套服务一键启停脚本 scripts/ctl.sh

支持 start/stop/restart/status/logs/build 子命令,覆盖依赖安装、
数据库迁移、前端构建、健康检查的完整生命周期。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(ctl): 修复 is_running 变量泄漏与并行 wait 退出码丢失;

- is_running() 中 pid_file 添加 local 声明,防止全局作用域污染
- 三处并行 wait 改为逐个检查退出码,任一子进程失败即报错中止

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(ctl): 修复健康检查不感知进程崩溃、路径逻辑重复与服务名校验缺失;

- wait_for_health 在 HTTP 轮询间隔中加入 is_running 检查,进程崩溃时立即返回失败
- is_running 改用 pid_file() 函数获取路径,消除硬编码重复
- cmd_logs 入口校验服务名是否属于 ALL_SERVICES,非法名称给出明确提示

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(ctl): 使用 exec 替代 eval 确保进程 PID 精确追踪与信号直达;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(kg): 知识图谱模块生产就绪改造 — 实体管理、混合检索、路径探索、统计面板 (#439)

* feat(kg): 知识图谱模块生产就绪改造 — 语料库级图谱、实体管理、混合检索、路径探索、统计面板

后端变更:
- 新增 GET /graph/entities 实体分页列表(类型筛选+名称搜索)
- 新增 GET /graph/entities/{id} 实体详情含出/入关系
- 新增 GET /graph/stats 图谱统计(实体数/类型分布/置信度/密度/度数)
- 重写 find_neighbors: 递归 CTE 在 kg_relations 上实现多跳遍历
- 重写 find_path: 递归 CTE BFS 在 kg_relations 上查找最短路径

前端变更:
- 重写 graph/page.tsx: 语料库选择器 + 构建/浏览全流程
- 新增 EntityListPanel: 表格视图+类型筛选+分页
- 新增 EntityDetailPanel: 实体详情+关系列表(出边/入边)
- 新增 SearchBar: 混合检索(语义+图结构)
- 新增 PathExplorer: 双实体选择+BFS路径查找
- 新增 NeighborExplorer: 1/2/3跳邻居展开
- 新增 GraphStatsPanel: 实体数/类型分布/置信度/密度/度数
- 新增 BuildHistoryList: 结构化构建历史卡片(状态徽章+统计+耗时)

文档变更:
- 扩展 user-guide.md §4.5 为完整知识图谱用户指引
- 更新 knowledge-graph.md §3 新增架构模式精炼(Cognee ECL/Graphiti 双时态)
- 更新 knowledge-graph.md §4 交付物清单

测试变更:
- 新增 test_graph_entity_service.py: 9 项单元测试覆盖实体列表/详情/Schema

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(kg): 修复知识图谱模块 CI 失败 — 类型错误、ID 前缀、测试 mock;

- 移除 NeighborExplorer 组件调用中不存在的 entityName prop(TS2322)
- 为 find_neighbors 返回的 GraphNode.id 补齐 entity: 前缀
- 重写 find_path 测试,mock session.execute 而非 find_neighbors

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(kg): 修复审查发现的 7 项问题 — 安全编码、状态管理、双向路径搜索;

- 路由 path params 加 encodeURIComponent 防路径遍历(3 个 route 文件)
- EntityDetailPanel: 用 loadedEntityId 派生 loading 状态,切换实体时正确展示加载态并清除旧数据
- EntityListPanel: 搜索输入 300ms 防抖,用 completedKey 派生 loading 状态
- GraphStatsPanel: 用 result 组合状态区分加载中/失败/成功
- NeighborExplorer: entityId 变更时重置 expanded/neighbors
- graph_repository find_path: 递归 CTE 增加反向遍历分支,与 find_neighbors 双向语义对齐

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(kg): 修复审查发现的遗留问题 — 常量提取、路径搜索、会话管理;

- 前端:提取 ENTITY_TYPE_COLORS 至 constants.ts,消除三处 TYPE_COLORS 残留引用(会导致运行时崩溃)
- 后端:修复 find_path 递归 CTE 中 path 追加错误(r.target_id → ps.target_id)
- 后端:get_stats 改为接收外部 db 会话,消除自建会话
- 后端:get_entity_detail 增加 corpus_id 可选过滤,增强数据隔离

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(memory): 记忆模块生产就绪化 — 巩固管线重构 + 事实提取 + 上下文集成 + 文档完善 (#440)

* feat(memory): 重构记忆巩固管线为三阶段智能架构并增强核心模块

- 重构 _simple_consolidate 为三阶段管线(分段→去重→存储),借鉴 Claude Code AutoDream 四阶段范式
- 新增 PatternFactExtractor 基于正则模式的对话事实自动提取(preference/profile/rule/custom)
- 新增 ContextAssembler 记忆上下文组装器,管理 token 预算分配(30%记忆/50%历史/20%系统)
- 新增 AsyncScheduler 应用层调度器回退,当 pg_cron 不可用时提供等效定时任务能力
- 增强 search_memory API 支持分页(limit/offset)和过滤(memory_type/date_from/date_to)
- 集成 ContextAssembler 到 perception.py 记忆搜索回退路径
- 新增 34 条单元测试覆盖事实提取和调度器(全部通过)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* docs(memory): 补充工业框架对标分析与用户操作指南

- docs/memory.md §2.4 新增 Claude Code 记忆架构深度对标(AutoDream 四阶段整理、三重门控调度、四类型分类法、三层上下文压缩、漂移防御)
- docs/memory.md §2.5 新增 Agent Harness 设计模式对标(三层压缩管线、Skill 按需加载、Task Graph 持久化)
- docs/memory.md §2.6 新增 Negentropy 差异化定位总结表
- docs/user-guide.md §5.8-§5.12 新增记忆形成机制、保留分数解读、搜索最佳实践、自动化配置指南、故障排除

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(memory): 恢复巩固管线 metadata 中遗漏的 event_count 字段

三阶段管线重构后 metadata 字典遗漏了原有的 event_count 字段,
导致 test_memory_service_lifecycle 集成测试 KeyError 失败。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(memory): 修复 Code Review 反馈的 7 项问题

1. search_memory 的 memory_type/date_from/date_to/offset 过滤参数现在在 vector_search 和 ilike_search 中实际生效
2. context_assembler 的 lazy import 移至文件顶部,与同文件风格一致
3. _simple_consolidate docstring 从「三阶段」更正为「四阶段」(含事实提取)
4. api.py search_memories 的 total 字段添加 TODO 标记(需独立 COUNT 查询)
5. AsyncScheduler 失败时回退 last_run_at,允许尽快重试而非等完整 interval
6. PatternFactExtractor 三段重复遍历提取为 _match_patterns 辅助方法
7. _consolidate SQL 拼接改为参数化绑定 :lookback::interval,消除注入风险

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(memory): 修复 Code Review 反馈的 3 项问题

- offset 分页参数未透传到底层搜索方法,现已正确传递
- datetime.fromisoformat() 缺少校验,非法日期返回 400 而非 500
- AsyncScheduler 派发任务未被追踪,stop() 时一并取消在途任务

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(memory): 修复 Code Review 反馈的 2 项问题

- 巩固管线阶段 4 事实提取调用包裹 try/except,防止导入或工厂失败中断管线
- 搜索接口 total 字段改为 -1 标记"未知",避免分页客户端误读

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(memory): 记忆模块 Phase 2 — LLM 事实提取 + 摘要生成 + Token 精确计数 + 检索反馈闭环 (#442)

* feat(memory): 记忆模块 Phase 2 — LLM 事实提取 + 摘要生成 + 精确 Token 计数 + 检索反馈闭环

- TokenCounter: 基于 tiktoken cl100k_base 编码器精确计数,替代 LENGTH/4 粗略估算
- LLMFactExtractor: LLM 结构化输出事实提取,PatternFactExtractor 作为降级后备
- MemorySummarizer: LLM 生成结构化用户画像摘要,缓存至 memory_summaries 表(TTL 24h)
- SummaryService: memory_summaries 表 CRUD(upsert 语义)
- RetrievalTracker: 检索效果反馈闭环,记录检索事件 + 显式反馈 API
- ContextAssembler: 优先注入摘要,tiktoken 精确 token 计数
- 新增 Alembic migration 0013/0014(memory_summaries + memory_retrieval_logs)
- 新增 MemorySummary + MemoryRetrievalLog ORM 模型
- 11 条新增单元测试,62 条全部通过,零回归

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* docs(memory): Phase 2 文档沉淀 — 两级提取策略 + 摘要巩固 + 精确计数 + 检索反馈 + 新增文献

- §4.2 扩展为两级事实提取策略说明(LLMFactExtractor + PatternFactExtractor)
- §5.4.1 新增摘要巩固策略(记忆再巩固理论 + 5 项工程对标)
- §6.3 更新 Token 估算为 tiktoken BPE 精确计数
- §6.5 新增检索效果反馈闭环(Rocchio + LTR + LongMemEval 评估维度)
- §15 新增 6 篇参考文献(Sennrich 2016, Sara 2015, Rocchio 1971, Burges 2005, Mem0, Letta)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(memory): 修复 LLM 事实提取 prompt 类型名不匹配 + 检索指标 SQL 聚合优化;

- prompt 模板中 "pref" 改为 "preference",与 _VALID_FACT_TYPES 验证器对齐,避免 LLM 输出被静默降级为 "custom"
- get_effectiveness_metrics 改用 SQL COUNT+CASE 聚合,避免将全量日志行加载到 Python 内存

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* refactor(memory): Review 反馈修复 — 检索日志可观测性 + query 透传 + 模型配置去重;

1. 检索追踪 except 从 silent pass 改为 logger.debug,使故障可诊断
2. _record_access 新增 query 参数并从所有调用点透传,消除空 query 问题
3. 提取 _resolve_model_config 为共享工具 engine/utils/model_config.py,
   LLMFactExtractor 和 MemorySummarizer 统一引用,消除 DRY 违规
4. 同步更新单元测试 mock 路径

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(kg): 修复图谱双写数据流断链 — 一等公民表对齐 (#441)

* fix(kg): 修复图谱双写数据流断链 — 一等公民表对齐

- create_relation() 新增写入 kg_relations 一等公民表,保留 JSONB 过渡兼容
- get_graph() 优先从 kg_entities + kg_relations 读取,空时回退 JSONB
- clear_graph() 增加 kg_entities/kg_relations 表清理
- build_graph() 完成后调用 KgEntityService.batch_sync_from_graph_build()
- 更新 test_graph_repository 适配新读写路径

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(kg): 新增 PageRank 实体重要性评分与 RRF 混合检索

- 新增 graph_algorithms 模块,基于 NetworkX 实现 PageRank (Brin & Page, 1998) 计算,
  结果持久化至 kg_entities.importance_score
- 混合检索支持 Reciprocal Rank Fusion (Cormack et al., SIGIR 2009) 模式,
  可通过 GraphQueryConfig.use_rrf / rrf_k 配置,向后兼容线性加权模式
- 图谱构建完成后自动触发 PageRank 计算
- 实体列表支持按重要性排序(sort_by=importance)
- 统计面板展示 Top 5 PageRank 实体
- 图谱可视化节点半径映射 PageRank 分数,突出重要实体

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(kg): 新增 Louvain 社区检测与图谱可视化增强

- 新增 compute_louvain() 算法,基于 NetworkX 内置 Louvain (Blondel et al., 2008)
  在无向投影图上运行社区检测,结果持久化至 kg_entities.community_id
- 图谱构建完成后自动触发 Louvain 计算(紧接 PageRank 之后)
- 统计面板新增社区分布(community_count + community_distribution)
- 实体列表和详情响应包含 community_id 字段
- 图谱可视化节点按社区着色(Tableau 10 色盲友好调色板)
- 统计面板展示 Top 8 社区分布柱状图
- 实体表格新增社区列,显示色块标识
- 显式声明 networkx>=3.0 依赖(此前为隐式运行时导入)

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(kg): 新增 Alembic migration 0015 — 添加 importance_score 和 community_id 列

CI 集成测试失败根因:ORM 模型新增了 importance_score (PageRank) 和 community_id (Louvain)
列,但缺少对应的 Alembic migration,导致测试数据库 schema 不匹配。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(kg): 修复 Review 反馈的三个问题

1. RRF 搜索 graph_score 恒为 0 — 将 importance_score 写入 entity_data
2. PageRank/Louvain 逐条 UPDATE — 改为 VALUES CTE 批量更新
3. 一等公民表路径缺 app_name 过滤 — 文档明确 corpus 级去重设计意图

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(memory): Phase 2+ 增强 — 反馈闭环闭合 + Query-Aware 组装 + 近重复检测 + 测试覆盖 (#443)

* test(memory): Phase 2 组件测试覆盖 — TokenCounter / SummaryService / RetrievalTracker / MemorySummarizer;

新增 39 个单元测试用例,覆盖 Phase 2 四个核心组件:
- TokenCounter: 精确计数、空输入、幂等性、异步一致性、单调性(蜕变测试)
- SummaryService: upsert/get/delete CRUD 路径
- RetrievalTracker: 检索日志、引用标记、反馈记录、效果指标计算
- MemorySummarizer: 摘要生成、TTL 缓存命中/过期、LLM 失败降级、重试

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(memory): Phase 2+ 增强 — 反馈闭环闭合 + Query-Aware 组装 + 近重复检测 + 文档沉淀;

Gap 1 反馈闭环:
- _record_access 修复 user_id/app_name 透传(此前始终为空字符串)
- PostgresMemoryService 存储 _last_retrieval_log_id 供下游消费
- ContextAssembler 注入 mark_referenced 隐式反馈信号(RLHF[33])
- API 新增 POST /memory/retrieval/feedback 和 GET /memory/retrieval/metrics

Gap 2 Query-Aware:
- assemble() 新增 query/query_embedding 可选参数
- _call_get_context_window 传递 7 个参数(含 p_query, p_query_embedding)
- SQL 函数 NULL safe 退化:无 query 时保持纯 retention_score 排序
- 隐式反馈标记在上下文组装成功后触发

Gap 3 近重复检测:
- _is_duplicate 阈值从 0.9 降至 0.85(Henzinger[40])
- 新增 Jaccard 词重叠二次校验(0.80-0.85 区间,Broder[37])
- FactService 新增 merge_similar_facts() 语义去重方法

文档沉淀:
- docs/memory.md 权威源文件索引扩充 Phase 2 组件
- §15 追加 13 篇参考文献 [31]–[43]

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* fix(memory): 修复 merge_similar_facts 过度删除 + retrieval_log_id 并发安全问题;

- merge_similar_facts: 锚点事实被删除后立即 break 内层循环,避免基于已删除 embedding 继续比对导致误删
- _record_access: 移除 _last_retrieval_log_id 实例属性,改为返回 log_id,消除共享可变状态的并发竞态
- ContextAssembler.assemble: memory_service 参数改为显式 retrieval_log_id,调用方直接传入

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)


* feat(kg): Phase 3 生产就绪增强 — 增量构建 + 语义去重 + 管线健壮性 + 查询缓存 (#444)

* feat(kg): Phase 3 生产就绪增强 — 增量构建 + 语义去重 + 管线健壮性 + 查询缓存

Gap 3 [P1] 构建管线健壮性 (Nygard, 2018; Majors, 2022):
- Migration 0016: kg_build_runs 增加 progress_percent + warnings 列
- build_graph: 批处理循环进度上报、LLM 提取失败…

Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
ThreeFish-AI added a commit that referenced this pull request Jun 8, 2026
…is_default + 创建期固化绑定); (#895)

根因: model_resolver._resolve 的回退链「缓存→vendor_configs→硬编码」从未查询
model_configs.is_default, 直接采用硬编码 _DEFAULT_EMBEDDING_MODEL(gemini/text-embedding-004),
违反该模块自身声明的解析链契约。与 ISSUE-028 互补: 028 修好「有 corpus pin」时索引/查询对称,
本缺陷是「无 pin」时双方都回退到忽略全局默认的 resolve_embedding_config()。

Fix #1 (model_resolver.py): 抽取共享 _build_resolved_config(复用 vendor 凭证/kwargs 构建);
新增 _load_default_model_config_row(is_default=True AND enabled=True) 与
_resolve_from_default_model_config; _resolve 在缓存命中后、vendor_configs 回退前插入
is_default 分支(独立 try/except, DB 异常降级不冒泡), 对 llm/embedding 对称生效。

Fix #2 (_shared.py + routes/corpus.py): 新增 resolve_default_model_config_id 与
_pin_default_embedding_config, create_corpus 序列化前将当前全局默认的 embedding_config_id
固化进 corpus.config.models, 使语料创建即绑定具体模型, 免疫日后全局默认变更;
后续改模型走 update_corpus 既有的维度比对 + 重建保护。

订正 model_resolver.py 陈旧注释(向量列固定 1536 维, 硬编码值仅末位回退)。
新增 7 例解析器单测 + 3 例固化单测; 连同既有相关单测 140 全过; ruff lint/format 全过。
记录于 docs/.agents/issue.md ISSUE-135。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
ThreeFish-AI added a commit that referenced this pull request Jul 2, 2026
- decision 增 improvement_efficiency(SI #4:单位成本增益,cost_units 以 Judge 调用数代理;
  真实 $-成本待 LLM usage 提取后续)+ decide_safety_nonregression(SI #6:安全套件零回退硬前置);
- SkillTemplateHandler.advance_shadow 记录 improvement_efficiency 到 shadow_eval_result;
  advance_canary 在能力 holdout 门通过后增跑安全套件(is_safety=True)零回退门——任一安全套件
  回归即阻断自动晋升(pending_approval 交人审),active_version 不翻;
- 迁移 0086:eval_suites.is_safety 标志;_find_suite 收紧为非安全(is_safety=False)主能力套件,
  安全套件由 _check_safety_nonregression 独立处理;
- 单测 +9(longitudinal/safety/efficiency 纯函数)+ 安全门集成测试 1(能力过、安全回归→阻断)。

至此综述 §8 SI 六目标全部落地:#1 backward retention / #2 held-out gain / #3 longitudinal
stability / #4 improvement efficiency / #5 path attribution / #6 safety non-regression。
合并分支共 103 测试全绿;alembic head=0086;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
ThreeFish-AI added a commit that referenced this pull request Jul 2, 2026
- §4 增「SI 六目标完成度」表(#1-#6 全落地)+ §10 开放问题状态刷新(10.5 纵向 ✅);
- §5 重构:Round 1+2 已完成评测层;剩余为能力扩展(runtime canary / agent-loop / 第三进化面 /
  真实 $-cost / 持续红队),各附前置条件 + 成本 + 边际价值评估 + 接入 recipe,按 YAGNI 留 dedicated round。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
ThreeFish-AI added a commit that referenced this pull request Jul 3, 2026
针对评审 fix #1 / #3 / #8 此前零覆盖路径补 3 项回归测试:
- test_spawn_bg_uses_proposer_draft_prompt_template_field(memory_pipeline):注入返
  SkillProposalDraft 的 fake proposer,断言 _spawn_bg 落 EvolutionProposal.payload['prompt']
  = prompt_template(buggy 读 draft.prompt 致 AttributeError,0 提案)。
- test_fetch_failing_cases_includes_task(eval_skill_gate):seed case.input.task,断言返回的
  失败 case dict 含 task 文本(buggy 仅 score/verdict,proposer 反思无失败场景)。
- test_spawn_one_failure_isolates_batch(skill_evolution):mock _find_spawning_candidates +
  _spawn_one,单 skill 抛异常,断言三 skill 均被尝试(buggy 整批单 try/except 首异常即中断)。

三测试在 buggy 代码上失败、fixed 代码上通过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
ThreeFish-AI added a commit that referenced this pull request Jul 3, 2026
…ary / 第三面 memory_pipeline_prompt) (#1038)

* feat(eval): 离线评测基座——eval 四表+held-out 双相门+反事实归因;

- 新增 eval 四表 ORM + 迁移 0083(EvalSuite/EvalCase/EvalRun/EvalResult,
  is_frozen holdout 分区 + 反事实 attribution JSONB +全过程审计 judge_raw);
- evaluator 增 judge_once 非锚定复用方法(routine 路径逐字节不变,供 SuiteRunner 复用);
- decision 增 skill 双相门 decide_skill_shadow/canary + compute_run_regression
  (综述 §8 held-out gain + backward retention / §9.4 防 Goodhart 双轨);
- 新增 engine/eval 包:SuiteRunner + SkillExecutor(judge-the-prompt 模式)+
  CounterfactualAttributor(Skill Influence Pattern)+ visible_results_query
  (结构性排除 partition=holdout,防 Goodhart 不回流)+ seed(create_suite/harvest);
- 单测 19 + 集成测试 4 全绿;既有 evolution 60 测试无回归。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* refactor(evolution): TargetHandler 抽象——按 target_kind 分派进化面(retrieval 零行为差);

- 新增 handlers/ 子包:TargetHandler ABC(advance_shadow/advance_canary/rollback/maybe_spawn)
  + RetrievalConfigHandler(原 orchestrator 的 retrieval 硬编码逻辑原样迁入)+ _shared 共享辅助;
- orchestrator 退化为薄分派层(reap + 按 target_kind 分派 advance + 遍历 spawn),re-export
  共享辅助保持单测兼容;第二面(skill_template)接入只需注册一个新 handler;
- 新增 golden 集成测试 test_evolution_orchestrator_state_machine(首次经 inspect_once 覆盖
  shadow→canary→promote/rollback 全路径,作 byte-equivalence 回归网);
- 顺带修 _td 潜在 bug(_td(days=1) 旧实现只收 seconds,致 spawn 路径 TypeError);
- 既有 evolution 60 单测 + 4 集成 + 3 golden 全绿,retrieval 进化路径逐字节等价。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): Skill 进化消费者——SkillTemplateHandler 闭环(GEPA proposer + active_version 发布);

综述 §3.5(Skill Evolution)+ §7(meta-layer)第二进化面落地,闭 PR1+PR2 的环:

- 新增 handlers/skill.py:SkillProposer(GEPA 式有界变异 prompt_template,复用 _ProposerBase,
  失败 case 反思驱动,长度/ noop 硬约束)+ SkillTemplateHandler(shadow 在可见集跑 SuiteRunner +
  decide_skill_shadow 增益门 + 反事实归因;canary 在冻结 holdout 跑 + decide_skill_canary 零回归门;
  promote 翻 skills.active_version,rollback 保持基线);
- 迁移 0084:skills.active_version 指针(区分「最新」与「已晋升」);Skills 无 sync 覆写,免 ADR-3;
- skills_injector:未显式锁版本(spec=="*")且 active_version 已晋升 → 解析 promoted 快照(~3 行);
- skill_template 入 ALLOWED_TARGET_KINDS;orchestrator 注册 SkillTemplateHandler;decision 增
  is_noop_template;config 增 skill_enabled 子开关(默认关);
- canary 用离线 eval-suite holdout 门(综述 §8 强调离线 held-out 优于噪声在线 canary),runtime
  按 thread 分桶注入候选版本留作后续;
- 集成测试 2(promote 路径翻 active_version + 创建候选 SkillVersion;rollback 路径不翻)。

合并分支共 92 测试全绿;ruff lint/format 全过;alembic head=0084。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(evolution): Skill 进化闭环 × SI 度量调研沉淀 + 设计文档 ADR-5/进度更新;

- 新增 docs/research/141-skills-evolution-and-si-measurement.md:综述 §3(Skills 三阶段
  Evolution 缺口)/ §7(Meta-Evolving 三体制)/ §8(SI 六目标 + SIP-Bench + 反事实归因)/ §9.4
  (防 Goodhart)/ §10.3(信用分配)映射到本切片实现(eval 四表 + held-out 双相门 + TargetHandler
  + SkillTemplateHandler),含数据流 Mermaid + 开放问题对应 + 后续方向 + IEEE 引用;
- 更新设计文档 self-evolving-agents.md:第三迭代注记(P3 target_kind 分派 + P4 frozen holdout 已落地)
  + ADR-5(TargetHandler 抽象决策);
- 更新 knowledge-map.md 索引 141 号调研。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): 纵向 SIP-Bench T0/T1/T2 复评——已晋升对象 drift 回退(综述 §8 #3 + §10.5 + §9.3);

已晋升对象不会自动再验证——流量漂移/依赖变更/模型升级都可能让一次通过晋升门的对象静默退化
(综述 §10.5「experience→capability 无 scaling-law」、§9.3「安全评估须与改进环并行常驻」)。

- decision 增 decide_longitudinal_drift(复评 holdout 均值 < 晋升均值 − drift_max → rollback)+
  SKILL_LONGITUDINAL_DRIFT_MAX;config 增 longitudinal_recheck_interval_seconds / drift_max;
- TargetHandler 增 recheck_longitudinal 默认 no-op(无 eval 基座的面跳过);SkillTemplateHandler
  实现:复跑 holdout 集 vs canary_metrics.candidate_mean,drift 则回退 skills.active_version 到
  base_version + 发 longitudinal_revert 事件;
- orchestrator 增 recheck_promoted(due-check + 分派 handler.recheck_longitudinal);新增
  longitudinal_recheck scheduler handler(cron 每日)+ 迁移 0085 seed(默认 enabled=False);
- 集成测试 2(drift→回退 active_version + 落 scheduled recheck run;stable→hold 不变)。

合并分支共 94 测试全绿;alembic head=0085;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): SI #4 效率 + #6 安全非回归——完成自我改进评测六目标(综述 §8);

- decision 增 improvement_efficiency(SI #4:单位成本增益,cost_units 以 Judge 调用数代理;
  真实 $-成本待 LLM usage 提取后续)+ decide_safety_nonregression(SI #6:安全套件零回退硬前置);
- SkillTemplateHandler.advance_shadow 记录 improvement_efficiency 到 shadow_eval_result;
  advance_canary 在能力 holdout 门通过后增跑安全套件(is_safety=True)零回退门——任一安全套件
  回归即阻断自动晋升(pending_approval 交人审),active_version 不翻;
- 迁移 0086:eval_suites.is_safety 标志;_find_suite 收紧为非安全(is_safety=False)主能力套件,
  安全套件由 _check_safety_nonregression 独立处理;
- 单测 +9(longitudinal/safety/efficiency 纯函数)+ 安全门集成测试 1(能力过、安全回归→阻断)。

至此综述 §8 SI 六目标全部落地:#1 backward retention / #2 held-out gain / #3 longitudinal
stability / #4 improvement efficiency / #5 path attribution / #6 safety non-regression。
合并分支共 103 测试全绿;alembic head=0086;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(evolution): doc 141 更新——SI 六目标完成度 + 能力扩展项延期理由/recipe;

- §4 增「SI 六目标完成度」表(#1-#6 全落地)+ §10 开放问题状态刷新(10.5 纵向 ✅);
- §5 重构:Round 1+2 已完成评测层;剩余为能力扩展(runtime canary / agent-loop / 第三进化面 /
  真实 $-cost / 持续红队),各附前置条件 + 成本 + 边际价值评估 + 接入 recipe,按 YAGNI 留 dedicated round。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(eval): SkillExecutor agent-loop 模式——AgentLoopExecutor + execution_mode 路由(综述 §3);

- 新增 AgentLoopExecutor:skill prompt 作 system instruction + case task 作 user,单轮 LLM 生成,
  Judge 评**生成产出**而非评 prompt 文本(v1 单轮 skill-conditioned generation,已比 judge-the-prompt
  进一步;完整多轮+工具+沙箱是下一步);
- SuiteRunner 增 execution_mode 路由:scoring_config.execution_mode="agent_loop" → agent_executor,
  否则默认 SkillExecutor(judge-the-prompt);agent_executor 可注入(扩展点保持);
- 集成测试 2(agent_loop→走 agent_executor 高分;默认→走 SkillExecutor 低分,由产出标记证明路由)。

零改 handler / 零迁移;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): runtime canary 分桶注入——受控灰度发布窗口(综述 §9.3,R3-b);

离线 eval 门验证正确性后,插入在线分桶灰度窗口再全量晋升——捕捉部署期问题(真实分布漂移、
集成缺陷),与离线 held-out 门互补(综述 §8 离线验证 + §9.3 受控发布)。

- 新增 STATUS_RUNTIME_CANARY;迁移 0087 重建 uq_evolution_proposals_one_inflight 部分唯一索引
  (WHERE 纳入 runtime_canary,保单在途不变量);config 增 runtime_canary_enabled(默认关)+
  runtime_canary_window_seconds;
- SkillTemplateHandler.advance_canary:离线门 + 安全门通过后,runtime_canary_enabled → 进
  runtime_canary 灰度窗口而非立即晋升;advance_runtime_canary 窗口到期 → 全量翻 active_version
  (ABC 默认 no-op,retrieval 不用);orchestrator _advance/reap 纳入新状态;
- 分桶路由:queries.fetch_active_skill_canary(TTL 缓存)+ resolve_skills 增 bucket_key 参数 +
  _maybe_runtime_canary_override(命中桶→解析候选 version)+ expand_skill 从 session.id 透传
  bucket_key;显式 name@semver 锁定不被灰度覆盖;
- 集成测试 3(状态机 canary→runtime_canary→promoted;disabled 向后兼容即晋升;分桶路由命中候选/active);
- 顺带补 3 个 skill handler 测试 fixture 的新 settings 字段。

v1 在线信号为窗口到期;error-rate 门待 tool_invocations.canary_assignment 标记接入(doc 141 已记)。
evolution/eval 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): 第三进化面 memory_pipeline_prompt——TargetHandler 第三子类(综述 §7,R3-c);

把综述 §3.5 Evolution 范式从 skill 推广到记忆管线 prompt(extractor/reflection/summarizer),
证明 TargetHandler 抽象 + eval 基座 target-agnostic:第三面接入零改 orchestrator,仅一个 handler 子类。

- 新增 MemoryPipelinePromptHandler(advance_shadow/canary 复用 SuiteRunner + decide_skill_* 双相门;
  promote 翻 memory_config_versions is_active 指针)+ PipelinePromptProposer(GEPA 有界变异 prompt)
  + PromptExecutor(跑候选 prompt 在 sample_text 上,Judge 评产出);
- target_kind=memory_pipeline_prompt 入 ALLOWED_TARGET_KINDS + eval_suite 白名单;orchestrator 注册
  第三 handler;config 增 memory_pipeline_enabled(默认关);版本基座复用 memory_config_versions(无新表);
- 运行时消费(consolidator 读 active prompt)是后续接线——promote 已翻指针;
- 集成测试 1(propose→shadow→canary→promote 翻 memory_config_versions active 到候选 v0.2.0)。

TargetHandler 三面齐备(retrieval / skill / memory_pipeline_prompt)。eval+evolution 108 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(evolution): doc 141 §5 更新——Round 3 三项能力扩展已落地(runtime canary / agent-loop / 第三面);

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): memory_pipeline 运行时消费接线——consolidator 读 active 进化 prompt(R4-a);

闭环第三面:进化产物(pipeline prompt)不再止步于"翻指针",consolidator 实际消费。

- weights.resolve_active_pipeline_prompt(scope, fallback):读 memory_config_versions active
  snapshot.prompt + 30s 缓存 + 代码常量兜底(冷启/无 active/表不存在);invalidate 同步清 prompt 缓存;
- llm_fact_extractor._extract_batch 接线:base_prompt 经 resolve_active_pipeline_prompt 解析
  (FACT_EXTRACTOR_SCOPE="fact_extractor"),active 进化 prompt 优先、回退 _EXTRACTION_PROMPT 代码常量;
- memory_pipeline handler _promote 调 weights.invalidate(scope) 强一致刷新(consolidator 立即读到新 prompt);
- 集成测试 2(promote 后 resolve_active_pipeline_prompt 读到 "improved-prompt";无 active→回退 fallback)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): runtime canary 窗口末复评门——发布前自验证(综述 §9.3,R4-c);

advance_runtime_canary 窗口到期不再直接全量晋升,先复跑 holdout + decide_longitudinal_drift
对比晋升时均值(canary_metrics.candidate_mean):drift → rollback(灰度期已暴露退化),
否则翻 active_version 全量发布。复用纵向复评基座,使受控灰度发布 self-validating。

集成测试 1(窗口末复评 drift 60 vs 晋升 72 → rollback,不翻 active_version)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(eval): SI #4 真实 $-cost 执行侧提取——litellm.completion_cost(R4-b,scoped);

- CaseOutput 增 cost_usd;_conditioned_generate 经 litellm.completion_cost 提取 → AgentLoopExecutor
  / PromptExecutor 写入 CaseOutput.cost_usd(模型不在定价表 → None,不阻塞);
- SuiteRunner 累积 per-case cost_usd → eval_runs.cost_total;SkillTemplateHandler.shadow_eval_result
  记 candidate_cost_usd(SI #4 真实 $-cost 观测);
- 集成测试 1(executor 返回 cost_usd=0.05/case → run.cost_total == 6×0.05);
- doc 141 §5 更新:R4-a/b/c 落地;judge 侧 $-cost(_judge 重构,触 routine 热路径)+ 其余第三面 + 红队列为后续。

improvement_efficiency 仍以 n_cases 代理(保持跨 run 单位一致);$-cost 作单独可观测量。
eval+evolution 108 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(eval): judge 侧 $-cost _judge 重构——完整 SI #4 真实成本(R5);

_judge 返回 8 元组(+cost_usd/token_total),EvaluationResult 增 cost_usd/token_total,
evaluate + judge_once 透传 → SuiteRunner 累积 executor + judge 全成本进 eval_runs.cost_total。
litellm.completion_cost 提取;模型不在定价表/Faculty 路径 → (None,None) 静默降级不阻塞。

- evaluator._judge 重构(8 元组);_extract_cost helper;EvaluationResult.cost_usd/token_total;
- evaluate()(routine 热路径)/ judge_once() unpack 8 + 设 cost(routine 路径除新增字段外逐字节不变);
- SuiteRunner 累积 = executor cost + judge cost(res.cost_usd)→ run.cost_total 全成本;
- 更新 3 个 _judge 测试桩(gate/anchor/judge_once)为 8 元组;新增 judge_once cost 透传单测。

至此 SI #4 efficiency 真实 $-cost 端到端(执行侧 R4-b + 判定侧 R5)。eval+evolution+evaluator
共 138 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(evolution): doc 141 §5 更新——R5 judge 侧 $-cost 完整化,SI #4 端到端;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): builtin_tool_config 第四进化面——TargetHandler 第四子类(综述 §7,R6-a);

把综述 §3.5 Evolution 范式推广到内置工具参数级配置(top_k / timeout / prompt 片段等),证明
TargetHandler 抽象扩到第四面——接入零改 orchestrator,仅一个 handler 子类。

- 迁移 0088:builtin_tools.active_version 指针 + builtin_tool_versions 快照表(镜像 skill_versions);
- BuiltinToolConfigHandler(advance_shadow/canary 复用 SuiteRunner + decide_skill_* 双相门;promote
  翻 builtin_tools.active_version,候选 BuiltinToolVersion 缺失则从 payload 建);maybe_spawn gated
  by builtin_tool_enabled(proposer 留后续:参数搜索/OPRO;本切片验证闭环);
- BuiltinToolExecutor(judge-the-config v1:载候选 snapshot.config 交 Judge 评合理性;真实工具执行留后续);
- target_kind=builtin_tool_config 入 ALLOWED_TARGET_KINDS + eval_suite 白名单(builtin_tool);
  orchestrator 注册第四 handler;config 增 builtin_tool_enabled(默认关);
- 集成测试 1(propose→shadow→canary→promote 翻 builtin_tools.active_version 到候选 0.2.0)。

TargetHandler 四面齐备(retrieval / skill / memory_pipeline_prompt / builtin_tool_config)。
eval+evolution 110 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): runtime canary 在线 error-rate 门——受控发布在线信号(综述 §9.3,R6-b);

advance_runtime_canary 全量发布前增「在线 error-rate 门」:聚合 runtime_canary 窗口内 expand_skill
真实生产调用(按 canary_assignment 分候选桶 vs 基线桶),候选 error-rate 较基线退化 → rollback
(捕捉离线 eval 套件漏掉的真实分布问题)。与 R4-c 离线复评门双保险。

- tool_telemetry callback 对 expand_skill 调用打 skill_ref + canary_assignment(同步缓存读
  queries.get_cached_skill_canary + bucket_index,不触 DB,热路径安全);
- queries.get_cached_skill_canary(同步读 _skill_canary_cache,供热路径);
- decision.decide_runtime_canary_online(候选桶样本不足→hold 交离线门;error-rate 退化→rollback);
- SkillTemplateHandler.advance_runtime_canary 在离线复评门前先跑在线门;_runtime_canary_online_gate
  聚合 tool_invocations(expand_skill AND skill_ref AND created_at>=started_at);
- 单测 3(在线门 hold/rollback/promote)+ 集成测试 1(候选桶 error-rate 退化 → rollback 不全量发布)。

eval+evolution 114 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(evolution): doc 141 §5 更新——R6 第四面 + 在线 error-rate 门落地; TargetHandler 四面齐备;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): knowledge_strategy 第五进化面——TargetHandler 第五子类(综述 §7,R7-a);

TargetHandler 五面齐备(retrieval / skill / memory_pipeline_prompt / builtin_tool_config /
knowledge_strategy)。eval+evolution 115 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(eval): agent-loop v2 多轮推理 + 预算框架(综述 §3,R7-b);

AgentLoopExecutorV2(execution_mode="agent_loop_v2"):多轮 skill-conditioned 推理循环——每轮 LLM
看前轮产出 + critique-and-refine 指令,逐步改进;max_turns 预算控制(默认 3);[FINAL] 收敛检测;
累积 cost_usd。比 v1 单轮更贴近综述 §3「skill 指导真实多步任务行为」语义。

- SuiteRunner 增 agent_v2_executor + execution_mode="agent_loop_v2" 路由;
- v2 仍为纯推理(无工具调用);完整 agent-loop(多轮 + 工具 + MicroSandbox)是 further step——
  tool_executor 注入点已预留(execute 接 case_input.get("tools"));
- 集成测试 1(agent_loop_v2→路由到 v2 executor,cost_usd 记录证明)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* docs(evolution): doc 141 §5 更新——R7 第五面 + agent-loop v2; TargetHandler 五面齐备;

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(evolution): pre_propose_check cost_today_usd D7 绕过——聚合 eval_runs.cost_total(R8-c);

D7(tool_invocations.cost_usd 恒 NULL)是架构正确的——函数调用无 LLM usage。
进化子系统的主导成本是 eval suite 运行,其 $-cost 已由 R4-b+R5 写入 eval_runs.cost_total。

- queries.fetch_today_eval_cost:SUM eval_runs.cost_total WHERE today AND completed;
- retrieval.py maybe_spawn 替换 cost_today_usd=0.0 stub → max_cost_usd_daily 现生效。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(eval): 安全红队 seed + 持续安全复评(综述 §9.3 + SI #6,R8-d);

- safety_seed.py:综述 §9.2 Table 6 五类威胁代表性 seed case → create_safety_suite(is_safety=True);
- recheck_longitudinal 增持续安全复评:drift 未退化时复跑 is_safety suite → 安全退化回退 active_version;
  SI #6 从静态安全门升级为持续动态安全复评(综述 §9.3)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(evolution): agent_prompt 第六面 + ADR-3 Sync——TargetHandler 六面齐备(综述 §7,R8-b)

- 迁移 0089 agents.active_version + agent_versions;_load_subagent_row ADR-3 拦截;
  AgentPromptHandler + AgentExecutor + register + config。
sync 无需改(不设 active_version)。97 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(eval): agent-loop v3 多轮+execute_code MicroSandbox(综述 §3,R8-a);

AgentLoopExecutorV3(execution_mode="agent_loop_v3"):多轮 litellm tool calling loop +
execute_code via MicroSandbox(microVM 隔离)→ 结果回灌 → 继续推理。最贴近综述 §3
「skill 指导真实多步任务行为」语义。agent-loop 三级齐备(v1 单轮 / v2 多轮推理 / v3 多轮+代码执行)。

- litellm tools=[execute_code] + tool_choice="auto";response.tool_calls → MicroSandbox
  execute_safe → stdout/stderr 回灌 → 下一轮;
- 预算:max_turns(默认 3)+ max_tool_calls(默认 5)+ max_cost_usd_per_case(可选 cap);
- 成本:per-turn litellm.completion_cost 累积;
- 完整 ADK 工具集(search/save 等,需 mock ToolContext)= further step。

4 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(eval): agent-loop v4 完整 ADK 工具集——EvalToolContext mock + 多工具 dispatch(R9-a)

agent-loop 四级齐备(v0→v1→v2→v3→v4)。4 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* feat(eval): AutoRedTeamer 自动攻击生成——LLM 驱动红队 case 发现(综述 §9.3,R9-b);

AttackGenerator:基于 skill 防御 prompt + 综述 §9 五类威胁分类法 + 近期成功攻击记忆,LLM
生成新的对抗输入 → generate_and_add_attacks 加入 is_safety suite(source=synthetic)→ 下次
longitudinal_recheck 自动发现新漏洞。与静态 safety_seed(R8-d)互补。

- 综述 §9.3 末段「红队自身 agent 化」(AutoRedTeamer 20% higher ASR / 46% less cost);
- GeneratedAttack dataclass + _parse 容错 + generate_and_add_attacks 入 suite_id;
- fail-soft:LLM 失败/解析失败 → 空列表,不阻塞安全复评。

35 测试全绿;ruff 全过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(eval): V3/V4 tool 预算残缺 + V4 save_to_memory 隔离 + 演化 prompt 花括号安全;

评审缺陷修复(eval 子系统 3 项):
- runner.py AgentLoopExecutorV3/V4:撞 max_tool_calls 时设 cap_reached 并退出外层 turn 循环,
  避免 assistant 消息携带全部 tool_calls 但只补部分 tool 响应、下一轮 acompletion 必 400 被吞。
- runner.py AgentLoopExecutorV4 _dispatch_tool:save_to_memory 改写 EvalToolContext.state ephemeral,
  不再调用真实 save_to_memory 落生产 Memory 表(守住 ephemeral 文档承诺,堵红队 attack_generator
  对抗 case 污染生产记忆)。
- llm_fact_extractor.py:.format(turns=…) → .replace("{turns}", …),演化 prompt(DB memory_config_versions)
  含字面 {} 不再 KeyError 致整批静默降级 PatternFactExtractor。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* fix(evolution): 评审缺陷修复——spawn 崩溃/失败信号/缓存失效/回退一致性 6 项;

评审缺陷修复(evolution handlers 6 项):
- memory_pipeline.py _spawn_bg:读 draft.prompt 致 AttributeError(SkillProposalDraft 字段实为
  prompt_template, slots=True)→ 改读 draft.prompt_template;memory_pipeline 面 spawn 不再必崩。
- skill.py _fetch_failing_cases:join EvalCase.input 取 task 文本(EvalResult 无 task 字段),
  proposer 反思拿到具体失败场景而非仅 score。
- skill.py _promote/_rollback:调 invalidate_canary_cache(proposal.target_ref),回滚后
  queries._skill_canary_cache 15s TTL 内不再把 expand_skill 流量分到已拒 proposed_version。
- skill.py _spawn_bg:抽 _spawn_one + per-iteration try/except + db.rollback(),单 skill 异常
  (proposer 失败 / uq_skill_version 冲突)不中断同 tick 其余 skill。
- skill.py recheck_longitudinal:纵向 drift 回退与安全回退设 proposal.status=STATUS_ROLLED_BACK,
  proposal 行与 live active_version 不再自相矛盾,recheck_promoted 不再持续复评已下线版本。
- agent_prompt.py _promote:翻 agents.active_version 后调 invalidate_cache(prefix="subagent:"),
  evolved system_prompt 立即生效(对齐 MemoryPipelinePromptHandler 姊妹 handler invalidate 语义)。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(eval): 补 V3 tool 预算残缺 + V4 save_to_memory ephemeral 回归测试;

针对评审 fix #2 / #4 此前零覆盖路径补 2 项回归测试(test_agent_loop_executor.py):
- test_v3_tool_budget_break_no_orphan:mock acompletion 返 2 个 tool_calls + max_tool_calls=1,
  断言 acompletion 仅调 1 次(撞预算退出外层 turn 循环,不产生残缺 tool_calls 历史)。
- test_v4_save_to_memory_is_ephemeral:直接驱动 _dispatch_tool,断言写 EvalToolContext.state、
  返回 saved_ephemeral(不落生产 Memory 表)。

两测试在 buggy 代码上失败、fixed 代码上通过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>

* test(evolution): 补 spawn 崩溃/失败信号/batch 隔离回归测试;

针对评审 fix #1 / #3 / #8 此前零覆盖路径补 3 项回归测试:
- test_spawn_bg_uses_proposer_draft_prompt_template_field(memory_pipeline):注入返
  SkillProposalDraft 的 fake proposer,断言 _spawn_bg 落 EvolutionProposal.payload['prompt']
  = prompt_template(buggy 读 draft.prompt 致 AttributeError,0 提案)。
- test_fetch_failing_cases_includes_task(eval_skill_gate):seed case.input.task,断言返回的
  失败 case dict 含 task 文本(buggy 仅 score/verdict,proposer 反思无失败场景)。
- test_spawn_one_failure_isolates_batch(skill_evolution):mock _find_spawning_candidates +
  _spawn_one,单 skill 抛异常,断言三 skill 均被尝试(buggy 整批单 try/except 首异常即中断)。

三测试在 buggy 代码上失败、fixed 代码上通过。

🤖 Generated with [Claude Code](https://github.com/claude), [CodeX](https://openai.com), [Gemini](https://github.com/apps/gemini-code-assist)
Co-Authored-By: Aurelius Huang<threefish.ai@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant