{"current":"0.4.5","released":"2026-11-06","channel":"stable","count":21,"source":"CHANGELOG.md","entries":[{"version":"0.4.5","date":"2026-11-06","summary":"一句话：**运维可靠性批**——kb 向量索引启动预热（冷启动首查 37~90s→随启预热）+ video_variant 默认端点切本机套件（死域修复）+ officebridge 路径净化对齐 + 文档并集（M-06）。","sections":[{"title":"新增","items":["**kb 向量索引启动预热**（`app/main.py` `_warm_kb_vector_index` + lifespan 线程）：冷进程首查此前同步物化 75 万向量实测 37~90s（stage3-E P1）；预热失败仅告警，检索既有冷启自愈不变。","**video_variant 端点环境覆盖**（`CF_VV_LLM_ENDPOINT/CF_VV_LLM_MODEL/CF_VV_ASR_ENDPOINT`）：默认从死域 `api.tongqiansuanzhi.cn` 切 DS7452 本机 AI 套件（llm 11434 / asr 8100 实测路径）。"]},{"title":"修复","items":["**officebridge worker invocation_id 路径净化白名单化**（对齐 runtime `validate_path_segment`，封堵 `\\` 与 `..` 段——纵深防御，与体检 stage3-G P2 对齐）。"]},{"title":"文档","items":["**M-06 文档并集**（A 线 docs/经验库、A 侧 handoffs、A-AUDIT、GL6 账本等 180 文件并入部署谱系）。"]},{"title":"运维（数据/配置面，随批注记）","items":["40 个 github-raw 知识源 cadence 归零（国内网络不可达自动刷新，内容已随 bundle 入库）；","kb 异地备份链启用 14 天保留（drop-in + 立即裁剪 17 份）；孤儿行 3 行清理（备份先行）；","DOCKER-USER 外部封锁 6379/11211/8092/8098（UFW 对 DOCKER 链不生效的跨项目面封堵）。"]}]},{"version":"0.4.4","date":"2026-11-05","summary":"一句话：**BCD 统一候选上线**——KB 可见性合同、会员原子幂等、支付网关连接器 0.2.2 与video_variant 1.3.0 正式链路齐发；同批完成与生产 10-31 修复马拉松、官网工作台、A 线 M-01/02/04/05 的树级收敛（三线归一第一步，树=deploy/0.4.4，基线 codex/d-int07 f544a28c5）。","sections":[{"title":"新增","items":["**KB 可见性合同**（`app/knowledge/coding/visibility.py` 等）：私有/机构/平台三档授权 + 可信身份写绑定 + 全读面同授权 + 缓存失效；SSE 撤权反例收编；HTTP 写入面 admin 判定（N-01/C-SEC-06/07）。","**会员原子幂等/效果查询**：会员中心与 neural/cmdcenter 的授予-撤销时间线插桩与更严不变量（N-02/B-GOV-03）。","**支付网关连接器 0.2.2**（`app/payments/host.py|brick.py`）：宿主装配、分层合规名、manifest 键集对齐；`plugin.video.variant` 1.3.0 正式调用链装配与启动器入口（N-03/D-INT-06/D-INT-07 视频正式链）。","**网关动作级权限**（DEF-E）与**视频素材跨租户越权关闭**（DEF-F）；**SQLITE_READONLY 建库修复**（E-LAUNCH-02）；**读回 403 收口**（D-UX-FIX-01）。","**开发环境**：`scripts/devenv_backup.py`（382p）；dev_env_b 试用 --payments 有界授权；种子 actor 服务端推导（M-05，a_i19 连接重置根因修复）。"]},{"title":"修复","items":["**D-INT-04 全部**：C1 调用者身份归属 / C2 内部消费者读面收敛 / seed_goal 定义还原 / 桩网关 10053 真根因 / 支付授予步受信验收判据 / 网关台账连接锁族。","**D-INT-05**：DEF-A/B/C 三缺陷收口（链尾为准）。","**D-INT-06**：binding_guard 锁域覆盖 解析→检索→交付；B-VIDEO-03 生命周期与目录互斥。","**M-01/M-02 回迁**：consensus 法定人数与投票人自洽 / PER 缺输入可见 / training replay_buffer 四参数实参化 / 仓库防提权 / 共识层未接入生产的可断言声明 / wisdom calibrate 诚实化 / w18 测试隔离。","**生产 10-31 修复马拉松全量保真并入（84 文件取自生产树：45 领先整取 + 31 生产独有保留 + 5 分叉取生产版 + 3 盘点文档；另有 15 文件语义三方合并）**：网关审计 sqlite 共享连接加锁、能力调用跨平台路径与闸门顺序（开关>凭据>环境）、golden 数据集原子写与只读打开、kb 保留窗快照修复、eval 保护对象迁 data/protected/、opsloop 频窗上界、protect 重封签字、wisdom 探针服务身份、basetemp 回收、仓库卫生收口等——本批显式不回退任何生产已验证修复。"]},{"title":"测试","items":["整合分支 G1 定向复跑：version/changelog 一致性、gateway audit、capabilities、KB 可见性、dev_env_b、wisdom/perfopt 马拉松回灌族——结果见 docs/audit/stage3-C-20261105.md §整合分支构建记录。"]}]},{"version":"0.4.3","date":"2026-10-30","summary":"一句话：**知识库集合分区上线**——检索可按「经验/领域知识/语料/学习/自述」集合过滤，引用带稳定可点 URL，写入按 key 自动归位——百万条演进方案（docs/KB-百万条优化方案-20261030.md）P0+P1 落地。","sections":[{"title":"2026-10-30 官网业务工作台与积木统一规则","items":["**官网信息结构重整**：首页、积木工作台、业务方案、桌面端、能力目录和资源接入分工，视频与支付可直接找到。","**方案装配工作台**：读取真实能力目录，选择与追加业务组件、合并依赖、标注缺口，支持本机草稿保存恢复、JSON导入导出及带入命令窗口审查；不会自动安装、付款或调用收费模型。","**既有资产与遗漏检查**：视频变体、注册会话、会员中心及会员组件使用原生身份；源码资产、公开目录与外部连接器分开，不冒充全部可执行。","**统一准入**：旧能力和新增能力采用同一套身份、契约、依赖、权限、成本、证据与发布规则；兼容索引不授予发布权限，合规原生契约保持原样。","**真实部署状态**：按实际路由检查执行入口，生产缺新版总指挥/规则预览接口时禁用提交、保留草稿，不以网页200冒充执行接通。","**danao-guard MCP**：完成14工具发现和只读身份核查；治理适配器仍为候选，未自动启用写工具或远端执行。"]},{"title":"新增","items":["**集合（collection）体系**（`app/knowledge/coding/collections.py`）：五集合注册表+ 从 tags/标题族推导的纯函数规则（源自 2026-10-30 体检分类器三轮收敛，误判 <1.3%）；`KBStore.collection_map()` TTL 缓存索引；零 schema 写、零数据迁移。","**检索集合过滤**：`hybrid_search(collection=...)` 在排序/簇/多样性之前过滤候选（过滤时池子自动放大到 120 保 k 足额）；`service.search/answer` 透传；检索缓存键纳入collection（防串结果）。每条 hit 携带 `collection` 标注。","**API/公开面**：`/api/v1/kb/search`、`/public/search`、`/answer` 均接受 `collection` 参数（非法名 422）；/kb 页搜索框加集合下拉、命中条挂「引用定位 →」链接与集合徽标。","**引用定位协议**：citations 统一携带 `url`（`/kb?src={sid}&c={chunk_id}`）与`collection`；新增匿名单源详情端点 `GET /api/v1/kb/public/source/{sid}?chunk=` （脱敏、限流、404 语义完备）；/kb 页支持 `?src=&c=` 落点卡片（滚动+高亮）。","**写入即归位**：配置 `knowledge.owner_collections`（owner→默认集合），POST /documents 未显式带 `collection:` tag 时自动补标；单 owner 单日写入量观测告警（每 250 条 WARN，日志关键字 KBBULK）。","**kb_changes 保留窗脚本**（`scripts/kb_changes_retention.py`）：N 天窗删除，删前快照可整表还原，支持 dry-run。"]},{"title":"修复","items":["检索缓存键缺 collection 维度的串结果隐患（同查询不同集合共享缓存）——随本批修复。"]},{"title":"测试","items":["新增 `tests/test_kb_collections.py` 8 项：推导规则/端到端过滤/非法名 422/引用 URL/ 写入自动打标/单源详情端点（含 404 语义）；kb 全家回归 168 项全绿。"]}]},{"version":"0.4.2","date":"2026-10-30","summary":"一句话：**全项目深度体检即修批次**——六路地毯审计（A~J 十阶段）落地修复：向量检索从分钟级到亚秒、note 写入防碰撞、/mcp 不再阻塞全服务、学习链补上成本刹车，并完成生产 202.189.22.187 回迁后的首次**树级收敛**（生产 master 孤儿线收编本地 main）。","sections":[{"title":"修复（P0/P1 即修即部署）","items":["**向量检索 numpy 矩阵快路径**（E/C-P0，`app/knowledge/coding/store.py`）：库长到 74.8 万向量后逐行纯 Python 余弦单次检索分钟级（生产台账均值 181.9s / 最大 649.9s，匿名 /kb 检索 60s 超时）。新增内容代次物化索引（f32 矩阵 + 行范数，懒重建 + 60s 节流），检索退化为一次 BLAS 矩阵向量积（亚秒）；无 numpy/维度混杂自动回落原逐行路径，行为不变。新测试 `test_kb_vector_fastpath.py`（快慢路径结果等价）。当晚 v2：重建挪后台守护线程——请求路径绝不付全表扫描成本（任何 kb 写入后的首次检索不再出现 60~70s 重建墙，先用陈旧索引作答、换轨原子替换；冷启动首查仍同步建一次防回落分钟级逐行）。","**note 写入 sid 防碰撞**（C-P1，`app/knowledge/coding/service.py`）：旧制`sha1(title)[:8]` 仅 32bit，7.7 万文档量级生日碰撞可致「不同标题静默接管同 sid 条目」。新条目一律 16 位；既有条目（8/16 位）仅同标题按原 sid 稳定更新；sid 被不同标题占用即跳过并告警。新测试 `test_kb_note_sid_guard.py`（同标题=更新定律不破）。","**/mcp 不再阻塞全服务**（B-P1，`app/api/mcp.py`）：工具处理器是同步重活（LLM 30s/能力轮询 900s），原先在 async 端点内直接跑会卡死事件循环（含 /livez）。改 `anyio.to_thread.run_sync` 丢线程池；顺带 /mcp 接入 RateLimiter（与 REST 同语义）、admin 口令改常数时间比较（`secrets.compare_digest`，REST `deps.py` 同步修）。","**selfexperiment.revert 条件写**（B-P1，`app/brain/selfexperiment.py`）：回退只在该技能正文仍等于实验落盘版本（body==after_body）时执行；已被后续推进则拒绝（stale_body）并留审计，杜绝盲目回退抹掉并发改进。新测试 `test_selfexperiment_revert_cas.py`。","**主学习链接入每-topic 成本刹车**（B/C-P1，`app/api/service.py`）：learnroi.spend_brake 此前只挂在 relearn 一条路径，goal.advance/backfill/手动入队不查——同 topic 烧 token 无上限。现 _learn_executor 入口在全局额度闸之后立即查询，被刹 topic 返回topic_spend_brake。新测试 `test_learn_spend_brake_wiring.py`。","**LLM 兜底通道可观测**（I-P1，`app/evolution/llm.py`）：脚本车道兜底切未知价渠道（如未登记台账的中转）此前完全静默。现每通道一行 `LLMCHAN` 日志（失败/兜底=WARNING、主力成功=INFO，含 usage，绝不落 key），可直接 grep cron 日志。新测试`test_llm_channel_logging.py`。","**`.env` 进 .gitignore**（A-P0）：根目录 .env 含真实 key，未 ignore 时一次`git add .` 就会泄漏入库。","**/learning 管理口令改 sessionStorage**（C-P1，`app/web/learning.html`）：与 /console 安全姿态对齐——admin 口令不再持久落盘 localStorage（跨会话留存即泄露面）。"]},{"title":"运维","items":["**生产收敛（J 阶段）**：生产 master（103 时代孤儿快照线 5 提交）经 commit-tree 收编本地 main 树（保留双侧历史、零 reset/force）；生产 memory-venv 补装 requirements 缺失依赖（msgpack/jinja2 等 5 项）；`config.yaml` 盘外保全后以未跟踪文件还原。","**AGENTS.md 服务器现状注**（H-P1）：仓库与工作区两级 AGENTS.md 的迁移公告模板替换错误（两台老服务器 IP 写成同一个）修正为 2026-10-30 回迁现状。"]}]},{"version":"0.4.1","date":"2026-10-28","summary":"一句话：**线上代码进 git 了**——0.4.0 整批改动此前只存在于工作区（无版本保护），本批补提交入册；顺带清剿快照遗留的测试代次错配与树内杂物，测试体检恢复可用。","sections":[{"title":"修复（运维闭环，闲时批次 2026-10-28）","items":["**补提交 0.4.0 线上状态**（0e716fe，28 文件 +6310/-3150）：pager.js/about 页/kb 强化等自 10-25 上线以来首次进入 git 历史；生产仓从此工作区干净。","**测试套件对齐**（9af4c98）：快照内 12 个测试文件是比 app 模块更老的孤本（导入从不存在的符号，收集即错），用主仓版对齐恢复收集；0.4.0 关键回归子集36 passed / 1 skipped（分页合同、pager.js、版本链一致、kb 告警转发、内联 JS 语法）。","**树内归档**：树根 5 个历史 patch、2 个 .bak、5 个 _debug 测试 → `_patch_baks/`；旧 backup 目录 → `backups/`（只 mv 零删除）。"]},{"title":"已知边界（留给下个版本）","items":["14 个测试文件因主仓↔生产 app API 真分叉（97 文件热修未回流）无法对齐，收敛方案见主仓 `docs/部署一页纸-改代码到上生产-20261028.md`。"]}]},{"version":"0.4.0","date":"2026-10-25","summary":"一句话：**列表页都能翻到底了**——生产 `/kb` 公开来源 33,392 条、文档版本 11,698 条、`/capabilities` 68 项，原来各自写死一个 `limit` 就当\"分页\"，用户翻不到底而页面还写着总数。现在统一走一份分页组件，形态按数据量选（长期增长用上下页，卡片流用加载更多），并且\"新加列表却忘了分页\"会直接让测试变红。","sections":[{"title":"新增","items":["**`app/web/pager.js`：全站唯一的分页实现**（无依赖，UMD 导出以便 Node 直接断言）。两种形态：`renderPages`（上一页／页码／下一页 + 第 N–M 条、共 T 条）与`renderMore`（加载更多 + 已显示／总数）；纯逻辑 `paginate`／`pageList`／`mergeUnique`／`moreState`。窄屏（< 680px）自动收窗：页码窗口 2→1、上一页/下一页换成箭头，464 宽不再折行。","**`/kb` 公开来源分页（服务端，每页 50）**：33,392 条。原来固定 `limit=100`，页面写着\"共 33392 个来源\"却只渲染前 100 条——99.7% 的数据在界面上不存在。","**`/kb` 管理员来源分页（服务端，每页 100）**：同 33,392 条，且原来一次性拉全量、渲染 33,392 个 `<tr>`，直接是内存炸弹。","**`/kb` 文档版本分页（服务端，每页 50）**：11,698 条，原来看不到 11,648 个版本。","**`/kb` 问答留痕（每页 50）、近似重复复核队列（每页 100）分页**。","**`/kb` 复核留痕、草稿留痕**：日志型列表，追加式\"加载更多\"，终止条件看 `total` 而不是\"本页是否为空\"（审计记录会被清理，本页空但前面还有是正常的）。","**`/capabilities` 能力总库（前端，每页 12）**：68 项，加载更多 + \"已显示 12 / 68\"；改搜索词或换域时把已显示条数重置回第一页，否则从\"全部域\"切到只有 5 项的域会看到5 项却没有任何\"加载更多\"，像丢了数据。"]},{"title":"变更","items":["**`GET /api/v1/kb/sources` 加 `limit`（默认 200，上限 2000，`0` 表示不限）+ `offset` + `total`**。`count` 语义由\"总数\"改为\"本页条数\"，总数改看 `total`（唯一调用方是 `kb.html`，已同步）。","**`GET /api/v1/kb/versions` 加 `offset` + `total`**；**`/kb/reviews`、`/kb/qa` 加 `offset` + `total`**；**`/kb/reviews/actions`、`/kb/drafts/actions` 补 `total`**。统一口径：`count` = 本页条数，`total` = 总数，`offset` / `limit` = 回显请求参数。","**只读接口一律分页**：这一版之后，凡\"返回列表\"的公开读取接口都必须能报出 `total` 并接受 `offset`，否则前端无法判断\"是不是还有\"——分页条只能显示\"本页几条\"，等于没说。"]},{"title":"修复","items":["**`loadSources` 的 `.then(loadSources)`**：删除来源后回调收到的是 DELETE 的响应对象，一旦函数签名收 `page` 参数就会把它当页码算，直接 NaN。改成显式 `.then(function () { … })`。","**`loadQA` / `rateQA` 同款问题**（`.then(loadQA)`），一并改成显式调用。"]},{"title":"验证","items":["**`tests/test_pager_js.py`**：Node 真跑 `pager.js`，**45 条边界断言**——0 条／1 条／恰好整除／整除多一条、页码越界（过大／0／负数）收敛、`pageSize=0` 不除零、非数字不产出 NaN、页码窗口（少页全列／多页首尾+窗口／两端不留孤立省略号）、去重合并、加载更多终止条件。**变异检验 10/10 全杀**（`ceil`→`round`、`<`→`<=`、去掉除零兜底、序号从 0 起、页码不收敛、gap 判据放宽、去重失效、终止条件放宽、窗口上界算错），复原后 md5 一致。","**`tests/test_pagination_contract.py`**：登记表 + 反向判据。① 每个登记项必须在页面里真的带 `offset` 或调分页器，判据做在\"URL 出现位置前后窗口\"里，不做整页搜索（整页搜索时删掉某一处 offset 依然绿，等于没写）；② 服务端分页的接口必须在 OpenAPI 里真的暴露 `offset`——抓的是\"前端传了、后端无视\"的假分页；③ 页面里出现的带 `limit=` 的列表请求，既没登记也没豁免 → 直接红（这是\"以后新列表忘分页\"的兜底）；④ 豁免必须写清\"为什么不用分页 + 数据上界\"，写 TODO／暂时 一律红。**变异检验 11/11 全杀**（逐页删 `&offset=`、删后端 `offset` 参数、新增未登记列表、豁免理由改 TODO）。","**`tests/test_inline_js_syntax.py`**：把每个页面的内联 `<script>` 抽出来交给 `node --check`。这些页面没有构建链，JS 写错只会\"整块不执行\"：页面照样 200、HTML 照样完整、pytest 照样全绿，只有人打开控制台才看得见——分页会整个消失而没有任何报错。"]}]},{"version":"0.3.9","date":"2026-10-25","summary":"一句话：**把「它怎么改自己」讲清楚**——`/about` 新增第 6 章「自我改进怎么运转」，补齐三条互补主线、三层改进回路、五类执行机制与证据分级；首页与全站导航不变。","sections":[{"title":"新增","items":["**`/about` 新增第 6 章「自我改进怎么运转」**（原第 6–11 章顺延为 7–12，锚点 id 全部未变）：三条互补主线（Harness² 改善当前任务的执行方式／Dream-RSI 改善探索、预算与停止策略／RRSI 约束修改幅度与过拟合）；三层回路（A 任务内适配、B 改进策略演化、C 能力资产发布）及其「共享同一份账本」的前提；五类执行机制（循环／工具使用／观察整理／上下文整理／完成判断）与「先定位跨任务重复失败、再限域、最后验交互」的顺序；四条同预算对照基线（原 H0／best-of-N 与固定重试／仅轨迹反思／拟议组合策略）；发现树重放的硬约束（只暴露当前前缀、看不到未来分支质量、未观察动作返回 unsupported、停止后不可再花费）。","**治理章新增「证据分级」**：`DEV_TRACE`／`PROMOTION_DECISION`／`AUDIT_ONLY` 三类访问权限，写明「归档不等于对提案者可见」，且检索、日志、错误响应、经验库守同一套约束—— 只要还剩一条旁路能读到隐藏答案，自我改进就退化成背答案。","**规划章补入 RSI 工作分组与验收合同**：RSI-00…15 映射进原有 159 项台账、不重复计完成，依赖方向（00→01/02→03/04→05、01/02→06→07→08、03/05/08→09、09/10→12→14）与可选支线（13／15）写清；RSA-01…12 的必备字段与几条最见真章的检验（前缀隔离、重放真实性、组合再执行、成本与恢复、不可改的控制边界、真正生效与回退、外部动作幂等）。同时明确「它同时是还没上线的清单」：分组是规划与验收口径，不代表机制已在运行。","**分级表 L5／L6 补入口**：L5 走循环 B（注册版本化提案／探索政策 → 同预算基线对照 → 独立未来任务确认 → 失败保留原策略）；L6 要求落在两个独立真实项目上，并留下「能力被再次调用」与「长任务可恢复」的证据。","**架构表「进化层」**补三层循环分工。"]},{"title":"变更","items":["**`/about` 页内目录标签收紧**，12 项在 1280 宽不再折行（如「分级与当前级别」→「分级与级别」、「自我改进怎么运转」→「改进怎么转」）；章节锚点 id 未变，既有外链不受影响。","**`meta description`** 增补「三条自我改进回路」。"]},{"title":"验证","items":["本地 `tests/test_site_shell.py` + `tests/test_version_changelog.py` **20 passed**。","新增用例 `test_about_page_covers_improvement_loops` 做变异检验：删证据访问类别、删回路免责句、删同预算对照、删未上线声明、删重放约束——**6 个变异体全部被杀**，页面复原后 md5 一致。","移动端 464 宽实测无横向溢出；桌面 1280 宽目录单行、三列回路卡对齐。","生产部署后逐页核验 `/`、`/about`、`/kb`、`/experience`、`/capabilities`、`/changelog`、`/api/docs`、`/learning` 与 `/api/version`。"]}]},{"version":"0.3.8","date":"2026-10-25","summary":"","sections":[{"title":"新增","items":["**「智脑介绍」升级为独立内页 `/about`**。内容由原先首页的一个栏目扩成十一块：它是什么、四条优势（含三维对比表）、怎么思考与做事（目标契约／三类未知／策略选择／预测与对账／停得下来）、分级体系（L1–L6 + 「判定三件事」+ 智慧八维度 + 意识五级副尺）、能力怎么长出来（五种粒度／缺失能力处理顺序／六级晋升路径）、现在能做什么（能力卡 + 性能与可靠性预算 + 三种接法）、技术架构（可信内核／可替换推理／持续积累资产 + 六层表）、治理与宪章（含「实现完成／受控验收／生产等级」三种完成状态分开登记）、后续规划（S0–S5 + 三条验收标志）、FAQ、如何开始。口径以 `docs/danao-智慧提升与生产落地-最终执行方案-2026-10-25.md` 为准；分级页明写「这套 L1–L6 是本项目自定口径，不是任何行业 AGI 认证」。","**路线图口径换成方案里的 S0–S5**：S0 检查点整合 → S1 一条可信工作链 → S2 三类可复用产品 → S3 测量式智慧提升 → S4 元改进与长期自主（L5／L6 入口）→ S5 机构生产交付。原 M0–M4 属研究附件，已被最终方案的阶段次序取代。"]},{"title":"变更","items":["**首页只保留「智脑介绍」开篇**：三行摘要 + 一个入口按钮，完整介绍迁出内页，避免同一份内容两处维护（历史上导航栏各页手抄一遍就是这个坑）。","**导航「智脑介绍」从跨页锚点 `/#about` 改为干净路由 `/about`**；全站导航仍由`app/core/site_shell.py::NAV_ITEMS` 一处定义，8 个公开页共用。"]},{"title":"修复","items":["首页「本页」导航里的「智脑介绍」原本指向另一个页面，与本页导航（只放页内锚点）语义不符，已移除。","`/about` 的页内目录原本半透明，滚动时下方内容会透出来，改为不透明并加分隔阴影。"]},{"title":"测试","items":["`tests/test_site_shell.py` **10 项全过**。新增／改写：`test_about_page_is_full_intro`（十一块锚点 + L1–L6 逐级 + 自定分级免责 + 三类未知 + 五种粒度 + S0–S5）、`test_homepage_only_teases_about`（**反向判据**：首页不许再出现分级阶梯与对比表，防完整介绍被复制回首页）、`test_active_item_matches_path` 覆盖 `/about`、旧直链 `/about.html` → `/about` 301。"]},{"title":"验证","items":["重启后 `NRestarts=0`、`/healthz` 200；`/`、`/about` 与其余六页均 200，剥掉 `active` 后导航片段哈希一致；`/about` 在 1440 与 464 两种宽度下均无横向溢出（宽表在卡片内滚动，不撑破页面）。"]}]},{"version":"0.3.7","date":"2026-10-25","summary":"","sections":[{"title":"新增","items":["**首页「智脑介绍」栏目**（`<section id=\"about\">`）。四块内容：A 项目定位与四类优势，附「通用大模型套壳 / 通用 Agent 平台 / 通千算智脑」三维对比表（记忆 / 学习 / 自我改进 / 治理 / 可复核）；B 自改进六级阶梯 L1–L6 逐级判定与当前级结论（L3 完整、L4 进行中）；C 六项生产计数与六类能力；D M0–M4 规划路径、三条「往智慧迈一步」的验收标志、五种复利资产。栏目内数字取 2026-10-25 生产快照，页面明写「分级是判断，不是宣传口径」。","**导航「智脑介绍」入口**。`app/core/site_shell.py` 的 `NAV_ITEMS` 增 `(\"智脑介绍\", \"/#about\")`，7 个公开页共用同一份导航（跨页锚点，不新增路由），改一处全站同步。"]},{"title":"修复","items":["**kb 页公开态判据过期**：`tests/test_site_shell.py` 的 kb 用例仍按旧的 `showGate(` 分支断言，改为断言 `loadPublicOverview()` 与 5 个 `/api/v1/kb/public/*` 出口。该条在本版之前的生产上是红的。","**更新日志加粗判据锚在会漂移的内容上**：`test_changelog_renders_bold_markup` 原先断言`<strong>进程边界</strong>`，而该短语属旧版本小节、`/changelog` 只渲染最新一节——发版即红，且红的原因与加粗渲染无关。改为从 `CHANGELOG.md` 最新小节自行推导 `**X**` 样本，并断言正文（剔除 `<code>` 后）不残留字面星号。变异检验：加粗不转换、加粗被吞两种变异均被判据杀死。"]},{"title":"测试","items":["`tests/test_site_shell.py` 9 项全过；新增 `test_homepage_has_about_section`（栏目 + L1..L6 逐级齐全）与 `test_anchor_nav_never_steals_active`（顶栏恰好 1 个 active，防「路径+锚点」双高亮）。"]},{"title":"验证","items":["生产重启后 `NRestarts=0`、`/healthz` 200；`/` `/kb` `/experience` `/capabilities` `/changelog` `/api/docs` 六页均 200，剥掉 `active` 后导航哈希一致；首页 `#about` 栏目锚点跳转实测落位正确。"]}]},{"version":"0.3.6","date":"2026-10-24","summary":"","sections":[{"title":"新增","items":["**KB 告警外部出口正式接线**。`DANAO_KB_ALERT_FORWARD_URL` 已配置（企业微信群机器人），`danao-kb-alert-forward.timer` 每 2 分钟检查并转发。此前 `configured:false` 状态解除，状态文件现在报 `{\"configured\":true,\"ok\":true,\"channel\":\"wecom\"}`。","`deploy/kb/kb_alert_forward.py --check`：发送一条链路连通性测试消息后退出，**不读写游标、不消费告警**，用于运维自证「现在通不通」。"]},{"title":"修复","items":["**报文适配**（`_adapt_payload`）。此前把 `kb-alerts.jsonl` 的原始行直接当请求体发出，而 IM 群机器人不接受自定义 JSON。实测企微对该形态返回`HTTP 200 + {\"errcode\":40008,\"errmsg\":\"invalid message type\"}`。现按目标域名翻译：企微/钉钉 → `{\"msgtype\":\"text\",\"text\":{\"content\":...}}`，飞书 → `{\"msg_type\":\"text\",\"content\":{\"text\":...}}`，未知域名原样发送（兼容自建接收端）。正文由 `_format_text` 渲染为可读文本，并按 UTF-8 字节截断至 1900 字节（企微上限 2048）。","**成功判据改看业务码**（`_verify`）。IM 机器人在参数错误、key 失效时一律返回 HTTP 200，只在响应体给非零 `errcode`。此前仅凭 `status_code < 300` 判定成功，会让「key 失效」显示为「发送成功」并推进游标，把告警永久丢掉——这是 0.3.5「游标吞失败」缺陷的更深一层。现在 `errcode != 0`（企微/钉钉）或 `code != 0`（飞书）即判失败、不推进游标、退出码 1。","状态文件新增 `channel`（wecom/dingtalk/feishu/generic）与 `last_error` 字段，失败时可定位原因且不回显 URL。"]},{"title":"变更","items":["`tests/test_kb_alert_forward_semantics.py` 由 5 用例扩至 **13 用例**，覆盖状态说谎、接线不成立、四种报文形状、字节截断、`--check` 不触游标。变异验证：换回 0.3.5 实现**10 failed / 3 passed**，恢复新版 **13 passed**。"]},{"title":"说明","items":["历史遗留：`kb-alerts.jsonl` 前 3 条告警在旧实现下被 `errcode 40008` 误判为成功、游标已推进至 3，**这 3 条不会补发**（分别是一条 `kb.test` 测试条目与两条健康分告警）。如需补发，只能手工重置 `/data/danao/kb-alerts.offset` 后重跑——会向群推送历史告警，易被误认为当前故障，故未执行。","钉钉若启用「加签」安全模式，需在 URL 上追加 `timestamp` + `sign`，当前实现未包含该步骤。"]}]},{"version":"0.3.5","date":"2026-10-24","summary":"一句话：**修掉三处「状态说谎」**——告警转发通道从未接线却报 `ok: true`、发送失败仍推进游标导致告警永久丢失、webhook 地址（含机器人 key）被打印进 journal。同时补齐 0.3.4 里「守卫会写 `kb-alerts.jsonl`」这句当时并不成立的说法。","sections":[{"title":"修复：告警链路的静默失真（`deploy/kb/kb_alert_forward.py`）","items":[]},{"title":"补齐：守卫的告警出口（`tools/check_fd_watermark.py`）","items":["ALERT 时除写日志外，追加一行到 `--jsonl`（默认 `/data/danao/kb-alerts.jsonl`），接入既有告警文件。**0.3.4 的 CHANGELOG 曾写「守卫会把异常写进本地日志与 kb-alerts.jsonl」，当时脚本并没有写 jsonl 的实现**——本版补齐，使文档与实现一致。","同一组告警在 `ALERT_REPEAT_SECONDS`（1 小时）内只写一次，避免每 10 分钟刷一条重复行（按告警内容签名去重，签名与时间戳存 state 文件）。"]},{"title":"测试","items":[]},{"title":"仍然存在（需人工决策）","items":["`/etc/danao/kb.env` 与 `/etc/youxi/alert.conf` **都没有任何生效的 webhook 键**，服务器上多套告警脚本都是「可选 webhook」且都没配。因此本版之后，告警的真实状态从「静默显示健康」变成「如实显示 degraded + pending 计数」，但**仍然没有人会收到推送**——要真正送达，需要提供一个 webhook 地址。"]}]},{"version":"0.3.4","date":"2026-10-24","summary":"一句话：**给 fd 事故装上可判定的回归守卫**——新增连接水位采样工具并装配为每 10 分钟的 cron，同时把「告警往哪里送」这件事查清：转发通道从未配置，状态文件却报 `ok: true`。","sections":[{"title":"新增：fd / 连接水位守卫（0.3.3 事故的回归哨兵）","items":["**工具** `tools/check_fd_watermark.py`：采样 `/proc/<pid>/fd`、指向 `danao.db` 的连接数、线程数与 `Max open files`。三条判据任一成立即 `rc=1`：① 连接数 ≥ `max(64, 线程数 × 2)`（事故形态是 500 连接 / 118 线程 ≈ 4.2×，正常 37 / 162 ≈ 0.23×）；② fd 总数 ≥ 4096（正常约 100，留 40 倍余量）；③ 与上次采样相比 fd 增长 ≥ 200（趋势判据，抓缓慢泄漏；只在同一 PID 内比较，避免重启前后串比）。","**为什么废掉「fd 使用率 > 70%」**：0.3.3 把 `LimitNOFILE` 提到 65536，70% = 45,824 个 fd，正常水位要涨 458 倍才触发——这是一条永不可能触发的死判据。判据的价值在于能否分辨故障。","**`rc=2` 是一等公民**：服务未运行、`/proc` 读不到等情况返回 2 而非 0。「测不到」与「一切正常」塌成同一件事，就是静默失效。","**装配**：`scripts/install_evolution_cron.py` 新增 `_fd_watermark_line()`，把守卫纳入既有`# DANAO-BRAIN-EVOLUTION` 单入口块（每 10 分钟，`--quiet`，异常才写 `logs/fd_watermark.log`）。走 installer 而非手改 crontab，避免下次安装被覆盖成两份。"]},{"title":"验证","items":["工具矩阵 8/8：正常 `rc=0`（fd 102/65536、conns 37、threads 162）、`--json` 输出、`--quiet` 静默、服务名不存在时 `rc=2`；三条判据各自变异（阈值压到 1 / 0）均按预期 `ALERT` + `rc=1`。","装配安全性用**集合差**证明：安装前后块外业务行 **106 → 106，丢失 0、新增 0** （其他项目 cron 全部保留）。副作用是块从文件中段移到末尾并多一个空行——installer 既有行为，故按行号定位块的做法不可靠，只能按标记。","`env -i` 干净环境下执行成功，证明不依赖 PATH 与登录环境。"]},{"title":"已知限制（未在本版解决）","items":["**告警没有外部出口**：`/data/danao/kb-alert-forward.status` 为`{\"configured\": false, \"ok\": true, ...}` —— `/etc/danao/kb.env` 里没有`DANAO_KB_ALERT_FORWARD_URL`，转发服务每 2 分钟空跑一次即退出。因此守卫当前只能把异常写进本地日志与 `kb-alerts.jsonl`（`kb-alerts.jsonl` 里已积压一条从未送出的 `健康分偏低：36` 告警）。","`ok: true` 与 `configured: false` 同时出现，属 fail-open 语义：未接上的守卫会伪装成已生效。该语义在 `deploy/kb/kb_alert_forward.py`，本次未改动（需先确认 webhook 目标）。"]}]},{"version":"0.3.3","date":"2026-10-24","summary":"一句话：**修复 fd 耗尽**——`ThreadLocalConnection` 每回收一个线程就永久泄漏 2 个 fd，服务跑约 2 小时把 1024 软限额吃满，此后所有需要打开文件的请求全部 500（经验库写入失败），而 `/healthz` 仍报 200。本版把连接按线程 ident 归档并在建连时惰性回收，同时抬高 `LimitNOFILE`。","sections":[{"title":"修复：连接随线程回收（生产事故复盘）","items":["**现象**：`/kb` 页面 500、`/api/v1/kb/documents` 写入失败；`/healthz` 200、无 Key 的接口仍正常 401。进程 fd 实测 **1023/1024**，其中 `data/danao.db` 500 个 + `danao.db-wal` 500 个，基础 fd 仅 23；首次报错 `OSError: [Errno 24] Too many open files: app/web/index.html`（11:11 启动，13:07 耗尽）。","**根因**：uvicorn 同步端点跑在 anyio 线程池，`WorkerThread` 空闲 `MAX_IDLE_TIME=10s` 即被回收；`ThreadLocalConnection._all` 用 list 强引用每条线程连接、线程消失后无人关闭 ⇒ 每回收一个线程泄漏2 个 fd（db + wal）。两条常规修法经实测均不可行：sqlite3 连接不支持 `weakref`，`threading.local` 子类的 `__del__` 也不随线程结束触发（只随对象销毁）。","**隐藏放大项**：线程 ident 会被 OS 复用（实测连续 12 个线程拿到同一 tid）。若只按 ident 归档而从不过期，旧连接既不在表内、又不属于存活线程，只能等 GC —— 这是第一版补丁仍残留 `growth=44` 的唯一原因。","**修复**：`_all` 改为 `dict[thread ident, conn]`；建连时在锁内回收不在 `threading.enumerate()` 的条目并 `close()`，同一 ident 覆盖前先关旧连接（`alive` 在锁外计算，避免业务锁与 threading 锁反序）；新增只读属性 `open_connections` 便于排查 fd 水位。","**容量**：`danao-brain.service` 增加 `LimitNOFILE=65536`（此前未声明，实际沿用默认 1024）。","**验证**：判定「N 个建连线程后 fd 增量必须是常数」——旧实现 50 线程 `growth=100`、200 线程 `growth=400`；修复后 50 与 500 线程均为 `growth=3`。变异验证：换回旧 `db.py` 测试立刻红（`assert 400 <= 20`）。生产 60 次并发 `/kb` 请求后 fd 稳定 92、连接 35，40 秒后不变；`/kb` 由 500 恢复 200（48KB）。","**测试**：新增 `tests/test_threadlocal_fd_leak.py`（2 用例）锁死该缺陷。"]}]},{"version":"0.3.2","date":"2026-10-24","summary":"一句话：**生产追平**——把停在 0.2.1 的线上一次性同步到当前代码树（含 0.3.0 / 0.3.1 全部内容），并把 0.3.1 之后收口的站点外壳、探针、审计链与知识库存储层一起上线；版本三处一致、日志同源可查。","sections":[{"title":"本次同步（0.2.1 → 0.3.2）","items":["生产此前停在 **0.2.1（2026-10-21）**，本地已到 0.3.1：线上 `/api/version` 与 `/api/changelog` 只到 0.2.1（5 条），本次按 `scripts/sync_repo.py` 的安全流程（打包 → 校验上传 → 解包到 `repo.new` → 摘要比对 → 逐目录替换）整体替换；","同步范围：`app/ scripts/ tests/ docs/ tools/ deploy/ agent-skills/` + `CHANGELOG.md README.md pyproject.toml`；","部署前先在服务器留全量备份，部署后校验 `/livez`、`/healthz`、`/api/version`、`/api/changelog`、`/changelog` 与冒烟脚本。"]},{"title":"公开站：统一外壳（2026-10-23）","items":["新增 `app/core/site_shell.py`：7 个公开页共用一个导航/页脚真值源（`NAV_ITEMS`），不再每页手抄；","`/kb`：未连接时显示门禁而不是四个「加载中…」；支持一键导入 `.danao_key.txt`、清除凭据，401 时同步刷新所有面板；新增公开只读概览 `GET /api/v1/kb/public/overview`（只返回计数，不含标题/正文/URI），未连接也能看到库规模，点击检索页签给「导入凭据」按钮而不是红字；","`/learning`：改回 `X-Admin-Token`（原先提示 API Key，与接口实际鉴权不一致）；","`/changelog`：支持 `**加粗**` 渲染（含加粗包住行内代码的写法）；旧直链 `/kb.html` 等 301 到干净路由；新增服务端分页：`?page=1&per_page=3`，上一页/页码/下一页，越界页码夹到末页，页脚同样有分页器；","**公开脱敏模式（2026-10-24）**：新增 `app/knowledge/coding/redact.py`，公开检索/回答/来源统一出口脱敏（Key / 密码 / 私钥 / JWT / Cookie / 数据库连接串 / 内网 IP / 邮箱 / 手机号 / SSH 密钥路径）；新增 `/api/v1/kb/public/search|answer|sources|graph`，匿名只读、按 IP 限流 60 次/分、不写 `kb_queries`；`/kb` 未连接时可脱敏检索，结果带「公开脱敏」标记，完整正文/写入仍需 Key；","测试 `tests/test_site_shell.py` 锁住「所有公开页导航一致」。"]},{"title":"探针分层：/livez 与 /readyz（2026-10-22）","items":["`/livez`：只回答进程活着，不碰任何依赖，恒 200——编排器判「要不要重启」；","`/readyz`：查 brain 装配、独立短连接 DB 探针（1s 超时）、线程池水位（available=0 或排队 >2× 总量 → 503），探针自身不占线程 token；","与 `/healthz` 的分工写进注释，避免「探针恒真」与「探针拖死自己」。"]},{"title":"审计链：删改不再无痕（2026-10-22）","items":["`audit_log` 懒迁移 `prev_hash/entry_hash` 两列，新写入逐条串链（覆盖 prev_hash/ts/actor/action/detail）；","新增 `GET /console/audit/verify`：`ok=False` 时给出 `broken_at`，支持 `limit` 快速巡检；只读、不写被校验表。"]},{"title":"主动能力与随身渠道（0.2.1 之后）","items":["**服务心跳** `app/brain/proactive.py`：定时主动 turn，`NO_REPLY`=无事，忙时 busy_deferral 不排队；","**Dreaming** `app/brain/dreaming.py`：Light/REM/Deep 三阶段，Deep 六权重 + 三门槛才晋升，技能一律走人审；","**用户模型蒸馏** `app/brain/usermodel.py`：对话中提炼 preference/fact/decision/boundary/habit/lesson，重复出现加权，密钥模式入库前拦截；","**对话侧技能自造** `app/brain/chatteach.py`：只产出 `proposed`，绝不自动批准、不改已批准技能；","**闭环健康看板** `app/brain/loophealth.py`：连续零产出即告警，解决「死锁 4 天零告警」；","**Telegram** `app/brain/telegram.py` + `app/api/telegram_webhook.py`：chat_id+user_id 双白名单、secret_token 校验、入站内容走 UNTRUSTED 围栏、凭据只走环境变量。"]},{"title":"知识库存储层重写","items":["`app/knowledge/coding/store.py` 重写为独立 `kb.db`：来源/文档/块/卡片/查询/运行记录六类表 + FTS5（unicode61，CJK 按字切分）+ 向量 BLOB；","FTS5 不可用时自动退回 LIKE 并在 `kb_meta` 标记，不静默假装有索引；","**知识图谱/簇映射设来源上限**：只对 chunk 数前 400 个来源算语义边（生产 5880 来源时逐对余弦 >240s，`/api/kb/search` 直接超时；改后实测 graph 1.2s、cluster 1.1s、单次检索 4.2s，`nodes_total`/`truncated` 明示覆盖面）；","新增 `tools/api_contract.py`、`tools/contract_attest.py`、`tools/memory_budget.py`、`tools/doc_ref_drift.py` 等门禁/度量工具（不影响运行路径）。"]},{"title":"修复与运维","items":["**修复** `app/compliance/license_scanner.py` 未闭合字符串：该文件此前无法导入（发布即炸），现已通过 `compileall`；","**修复** `app/main.py` readyz 线程池段 `limiter` 未定义（NameError 被 `except` 吞掉，`threadpool` 恒 `readable:false`；改 `lim` 后线上返回 total=40 / available=40）；","SQLite 超时统一为 `SQLITE_TIMEOUT_S=30` / `SQLITE_TIMEOUT_RO_S=5`（可环境变量覆盖），新代码禁止字面量；","`evolution_runs.slot_key` 幂等迁移（先 ALTER 再建唯一部分索引），避免旧库在 `executescript` 建索引时炸掉装配。"]},{"title":"验证","items":["`python -m pytest -q tests/test_version_changelog.py`：代码 / pyproject / MCP / 页面四处版本一致；","`python -m compileall -q app`：全部模块可编译；","部署后 `/api/version` 返回 `0.3.2`，`/api/changelog` 条目数 8、首条 0.3.2；","`scripts/smoke_deploy.sh` 与服务状态通过。"]}]},{"version":"0.3.1","date":"2026-10-23","summary":"一句话：电脑操控多出第三只手——**nuphus-mcp 的语义闭环**（observe → candidate → execute → verify）与 **Chrome CDP**（23 个 browser_* 工具），和 agent_s（视觉）、uia（Windows-MCP 控件树）并列。","sections":[{"title":"新增执行器：nuphus（设备端）","items":["**运行器**：`scripts/nuphus_runner.py`，协议 2024-11-05 stdio；模型只看到不透明候选 id，坐标/句柄不出 MCP 边界；执行回执带 `effect/verification`，再用窗口标题二次复核（不靠工具自说自话）。","**安装**：`deploy/nuphus-mcp/install.ps1`（钉 0.3.3 + SHA-256/SHA-1 校验 + 强制纯 ASCII 路径 + 先清空再落地）。","**配置**：`computer_use.executor: nuphus`、`nuphus_mcp`、`nuphus_confirm_write`、`nuphus_deny_tools`；`danao_runner register --nuphus-mcp` 一并写进本机配置，老配置自动补默认值。","**白名单**：默认挡 `browser_import_cookies`（读用户 Chrome 配置）、`browser_evaluate`（页内任意 JS）、`browser_drag_files`（本地文件拖进网页）。","**台账**：每次 `tools/call` 落 `ledger.jsonl`（时间/工具/参数摘要/耗时/错误），结果回传`tool_calls/denied/confirmed_actions/ledger`。","**能力库**：新增提供方 `danao.device.nuphus`（对比结论改为\"控件确定性 vs 语义闭环 vs 视觉通用性\"）。","**验收**：`scripts/nuphus_accept.py` 七项全绿——自检 45 工具、窗口枚举、语义候选、set_value 写入、标题复核、窗口截图、白名单拦截；`--with-browser` 另验 CDP 导航 + 快照（snapshot 2362 字符）。"]},{"title":"真模型实测（DeepSeek，2026-10-23 本机）","items":[]},{"title":"设备链路实测（本机 server → 设备队列 → Runner → nuphus）","items":["`danao_runner` 的 `--windows-mcp` 参数**根本不存在**（`cmd_register` 却在读 `args.windows_mcp`）→ 注册必崩，已补。","心跳/领单只捕 `SystemExit`，一次 `ConnectionAbortedError` 就把常驻进程打死 → 改捕 `Exception` 退避重试。","`/control/task` 没按执行器选提供方，台账永远显示默认 `uia` → 按 executor 映射到 `danao.device.nuphus`（库里没有就回退默认），并同步 `CATALOG_VERSION` 到 `2026-10-23.5`。","**Runner 必须用不受文件沙箱限制的解释器启动**：用项目 venv 跑时，它派生的 nuphus-mcp 连桌面锁都建不起来（`automation lock tmp create failed: os error 5`）；换系统 Python 后正常。另外两处收尾：","**追加不再覆盖原文**：新进程第一次就\"另起一行\"时不知道原文，改成\"定位文末 + 剪贴板粘贴\"（实测保留住\"第一行 A\"）；","**凭据不落盘**：`nuphus_model_e2e.py` 不再把 key 写进 `spec.json`，改走子进程 `DANAO_MODEL_API_KEY`。"]},{"title":"网页执行器增强（0.3.1 迭代，2026-10-24）","items":["**抗 @N 漂移**：页面插入节点会把 @N 顶走，而过期引用**往往仍然存在**（只是指向别的元素）。现在记住\"模型看到的那份快照\"的元素身份（role+name），引用对不上就按身份重定位，并在 history 里说明\"@3 已失效，按 '确认提交' 重定位到 @8\"。","**新增网页动作**：`btabs / bnewtab / bswitch / bback / bforward / bwait / bupload`；`wait_for` 在有网页会话时也看页面快照（不再只盯桌面候选）。","**上传**：路径白名单（只允许 `data/`、本次工作目录、`.tmp/`）；实测 0.3.3 用 `@N` 上传会在页内抛 JS 异常，自动回退 `input[type=file]`；上传后自动读页面文字作为确认，并挡住重复上传。","**btype/bpress 后立即刷新 @N**，避免\"点了旧引用\"。| 场景 | 结果 | 步数 | 耗时 | prompt / completion | |---|---|---|---|---| | 动态重排后点\"确认提交\"（旧 @N 失效） | succeeded | 5-6 | 17s | ~9k / ~330 | | 上传本地文件并读回文件名 | succeeded | 4 | 11s | 5026 / 284 | | 新标签页 + 切回第一个 | succeeded | 5 | 19s | 7178 / 1137 |"]},{"title":"生产侧预检（只读，2026-10-23）","items":["线上 `danao-brain 0.2.1`（2026-10-21），比本地 0.3.1 落后两个版本；","`app/api/devices.py`、`app/api/control.py`、`app/capabilities/devices.py`、`computer_use.py`、`scripts/nuphus_runner.py` **全部不存在**，`/api/v1/devices`、`/api/v1/control/*` 访问返回 404；","`computer_use` 未配置；`/data/danao/danao-brain-git` **不是 git 仓库**（无法 git pull）；","本地工作区有 1388 个未提交改动——直接打包会把别人的 WIP 带上线。因此**没有动线上任何文件**。启用方案、软链切换与回滚步骤写在[deploy/nuphus-mcp/PROD-ENABLE.md](deploy/nuphus-mcp/PROD-ENABLE.md)，等真人批准后再执行。"]},{"title":"为了跑通真模型改的五处（都是实测暴露的）","items":["**写入统一走 UIA SetValue**：`desktop_input` 的 SendInput 在中文输入法下会丢字（实测把\"第一行 A\"写成\" B第一行 A\"）；SetValue 不动输入法，回执可验证。","**追加 = 已记录内容 + 新文字整段重写**：执行器自己维护 `doc_state`，不再依赖光标位置。","**连续相同写入 = 收敛判定完成**：模型写完看不见结果会反复重写（实测 8 步全在重写），同一写入 + 回执 OK 出现两次即判 succeeded。","**解析宽松化**：模型偶发截断 JSON（如少了收尾引号），原来整步直接 fail；现在至少捞出 `action` 与字段继续执行。","**open 走分页名单 + 等新窗口**：应用名单每页 20 条，只读第一页会漏掉后半段；绑定后轮询新窗口并激活，避免模型以为没开成而反复 open。","**网页动作单独一套动词**（0.3.1 追加）：`browse / bclick / btype / bpress / extract / bclose`，网页元素用 `@N` 引用、桌面控件用编号；输入/回车后立即刷新 `@N`（页面重排会让旧引用失效）。有网页会话时**桌面动作直接拒**（实测模型会把 `type` 打到 Chrome 窗口上）；`extract` 取不到正文时退回可交互元素快照。百度结果页仍会 timeout——动态重排导致 `@N` 漂移，属于站点限制，不是执行器缺陷。"]},{"title":"实测坑（已写进脚本注释与 deploy README）","items":["二进制放在**非 ASCII 路径**（如 `D:\\ai项目\\...`）时，所有 `desktop_*` 工具报`automation lock tmp create failed`（os error 3/5）；装到 `C:\\nuphus-mcp` 即正常。","被**文件沙箱**限制的解释器（只允许写工作区）会复现同一个错误——runner 起跑前做`桌面锁` 预检并直接给出可操作的解释，而不是让模型十几步都在\"点不动\"。","版本线要分清：**桌面应用 1.0.0（2026-10-22）≠ nuphus-mcp 0.3.3（2026-10-13）**，两者独立发版；MCP 侧仍是 0.3.x，必须钉版本。"]}]},{"version":"0.3.0","date":"2026-10-23","summary":"一句话：能力库第一次接上\"**手**\"——从只会调 API，到能在真实桌面上点、打、滚。","sections":[{"title":"新增能力：computer.use（电脑操控 / 桌面自动化）","items":["**进程边界**：主应用（Python 3.14）不 import 任何 GUI 依赖；子进程跑`.venvs/computer-use`（Python 3.12 + gui-agents 0.3.2）里的`scripts/agent_s_runner.py`，spec/result 走 JSON 文件，可超时、可杀。","**适配器**：`adapter=\"agent_s\"`，长任务走后台线程（同 storyboard/aiduanju 模式），返回 `status=running` + `run_id`，轮询 `/api/v1/capabilities/runs`。","**素材**：每步截图落 `capability_assets`（image/png，meta 带 step/kind）。","**闸门**：默认 `enabled=false`；缺 key/缺端点/缺 venv 一律 409 并说明缺什么，绝不伪造\"点完了\"；`enable_local_env`（任意代码执行）默认关闭。","**配置**：新增 `computer_use` 配置段；凭据只认环境变量，库里只存变量名。优先级 config.yaml > 目录默认值 > 代码默认。","**模型**：默认接 **DeepSeek 官方**（`deepseek-flash`，视觉可用，一张图 ≤384 tokens）；规划实测正确，但坐标接地精度不足（偏差数百像素），详见 `docs/电脑操控-Agent-S.md` 第 7 节。正式点点点前建议换 UI-TARS-1.5-7B 接地，或改用 Windows-MCP 的 UIA 通道。","**干跑**：payload 传 `dry_predict: true` 只让模型\"看图出方案\"、绝不落地键鼠，用于接线自检。"]},{"title":"新增：设备接入（T1，让任何用户用自己的电脑）","items":["**服务端**：`app/capabilities/devices.py`（设备注册/令牌哈希/任务队列/租约/配额）+ `app/api/devices.py`（`/api/v1/devices/*`，用户侧 `X-API-Key`、设备侧 `X-Device-Token`）；","**用户端**：`scripts/danao_runner.py`（register / run / status），调本地 Agent-S 执行并回传；","**护栏**：单设备串行、服务端封顶步数/超时、`enable_local_env` 强制 false、每日额度、租约到期自动回队、排队超时 expired；","**文档**：`docs/电脑操控-用户端Runner.md`（用户安装/下单/排障全流程）。"]},{"title":"补齐：能力库 ↔ 设备桥接、托盘、闸门","items":["**桥接**：`computer.use` 新增 provider `danao.device`（`adapter=\"device\"`）并设为默认—— 调用方只需 `POST /capabilities/computer.use/invoke`，服务端自动挑一台在线设备排队，结果（含每步代码与最终截图）回到 `capability_runs` + `capability_assets`；没有在线设备 → 409，不假装跑过。","**闸门**：受限能力由\"仅管理端\"改为\"管理端 **或** 持 `computer:use` scope 的 key + confirm\"，执行仍在用户设备上，不在服务端。","**托盘**：`scripts/danao_tray.py`（状态灯、停止当前任务、打开日志、开机自启、退出），`danao_runner.py autostart --enable/--disable`（写启动文件夹，不碰注册表）。","**实测**：起服务 → 注册设备 → 托盘领单 → `/capabilities/computer.use/invoke` → run=3 `succeeded`（provider `danao.device`，1 步，截图落为 asset#1）。"]},{"title":"新增：UIA 执行器（标准控件走 Windows-MCP）","items":["`scripts/uia_runner.py`：Snapshot → 过滤可点元素（丢掉 OCR 的 word 碎片）→ DeepSeek 选一个动作 → **按元素坐标执行**（`Click/Type/Scroll` 的 `label` 参数其实是整数元素 id，传字符串会被 pydantic 拒，所以统一换算成控件树里的坐标走 `loc`）；","目录新增 provider `danao.device.uia` 并设为默认，`danao.device`（视觉）作为兜底；","`computer_use.executor` / `windows_mcp` 配置项；Runner 按 `payload.executor` 选脚本；","实测：任务「打开记事本」15 秒完成（`open notepad (win+r)` → 模型确认窗口标题 → done）。"]},{"title":"UIA 策略层打磨 + 端到端打通","items":["**窗口校准**：开场与每步都用 ctypes 直连 Win32 确认目标窗口在前台（绕开会挂 60s 的 `App` 工具）；","**打开验证**：`open` 后 6 秒内没出现目标窗口 → 明确报\"打开失败\"回给模型；","**失败预算**：连续 3 步编标签/工具报错就收手，不再烧步数假装在干活；","**输入前先点击**目标控件，并给编错的标签提供 3 个相近候选；","**端到端实测**：`POST /capabilities/computer.use/invoke` → provider `danao.device.uia` → 托盘 Runner 领单 → UIA 执行\"打开记事本并输入 hello uia\" → `run succeeded`，窗口标题变成`*hello uia - Notepad`，截图落 asset#3。"]},{"title":"新增：小白操作面板 `/control`","items":["`GET /control`：单文件页面（无鉴权，key 只存在浏览器 localStorage）；","`GET /api/v1/control/devices` / `POST /api/v1/control/task` / `GET /api/v1/control/task/{id}` / `POST .../stop` / `GET .../latest`：**只要求 `computer:use` 一个 scope**，截图直接内联成 data URL（省掉再去素材接口鉴权）；","`?key=xxx` 可一次带入并立即从地址栏抹掉，方便直接发链接；","打开页面自动显示\"上次任务\"，避免小白跑完就找不到结果；","实测：面板 -> 设备 -> UIA 执行\"打开记事本输入…\" -> `succeeded`，3 步，截图回显。"]},{"title":"面板完善：本机 Runner 一键启停 + 历史任务","items":["`GET /api/v1/control/runner`：读 `runner.state.json` 心跳判断\"本机 Runner 在不在跑\"；`POST /api/v1/control/runner/{start|stop}`：**仅回环地址**（127.0.0.1）且需 `computer:use`，远程请求一律 403——启停的是服务器这台机器上的进程，不能给别人用；","`GET /api/v1/control/history`：最近任务列表，点一条可回看步骤与截图；","页面：设备自动刷新（10s）、`Ctrl+Enter` 执行、\"再做一次\"、跑完自动刷设备/历史/Runner 状态；","控制台 `/console` 顶栏加「电脑操控 ↗」入口；","Runner 每次循环写 `runner.state.json`（pid/时间/设备号，**不含 token**），退出即删。"]},{"title":"顺带","items":["目录版本 `CATALOG_VERSION → 2026-10-23.4`，启动即幂等重灌，新能力自动出现在`/api/v1/capabilities` 与控制台。","文档：`docs/电脑操控-Agent-S.md`（架构、配置、调用、限制、排障）。","测试：`tests/test_computer_use.py` 9 条（目录登记、三道闸门、spec 组装、结果裁剪、台账+素材落库），不启动 GUI、不点鼠标。"]}]},{"version":"0.2.1","date":"2026-10-21","summary":"一句话：把**死掉的**自进化闭环真正打通——洞见不再只是记忆里的记录，而是能变成技能补强提案、跑完 A/B 复测、并被证据裁决保留还是回滚。","sections":[{"title":"闭环修复（生产实证）","items":["**目标不关闭 → 计划建不出来（主因）**：计划终局时同步收口目标（`_close_plan_goal`），接管历史遗留的僵尸目标（`adopt_existing_goal`），并主动扫描升级前的残留（`sweep_zombie_goals`）——死锁固化在库里，升级代码不会自动治好\"过去\"。","**谓词前缀污染 → 目标永不满足**：标题是「学习需求：」+「评测缺口：」+ 核心的复合串，只剥一层会让类别词残留并稀释重叠系数；改为逐层剥离（`core_topic`）。","**捕获走全库反查 → 捞到负样本**：web_learner 的\"该页面只是产品清单，未涉及…\" 描述的是**没学到东西**，不能当洞见写进技能；改为取任务自带的洞见正文 + 负样本判定。"]},{"title":"顺带修掉的真问题","items":["`_skill_covers` 基于**命题核心**判定，修复类命题（评测/路由缺口、技能失效修复）不被\"已被技能覆盖\"阻拦——技能存在但失效正是要修它的理由。","复评退避判据**方向写反**（`closed >= last_eval` 实为\"没有新评测\"）→ 天天重学同一道题。","捕获覆盖面：真洞见多来自 `failed_check`（技能失效修复），原先只认 `eval_gap` → 学到了也丢弃。","固定 `LIMIT` 的全表拉取会**静默丢弃**目标（2092 条技能里 800 条窗口外）→ 改为 DB 侧匹配。","`failed_check` 无退避 → 同一主题 3 分钟内连立 3 次全失败，纯烧钱；改为失败后冷却。","retired 技能的补强提案因 JOIN `status='approved'` 永久卡 pending → 标记 `orphaned`。"]},{"title":"修复前后对照（生产实测）","items":[]},{"title":"指标口径：区分「主动跳过」与「真失败」","items":["退避拦下、刹车拦下 → 状态 **`skipped`**（没做事，不是失败）","素材源全挂等尝试过但没产出 → 仍是 **`failed`**（真失败）","`skipped` **不会**触发失败退避（否则守卫互相锁死）`improve_plan` 从此有三态：`done` / `skipped` / `failed`。"]},{"title":"其它","items":["新增 `self_improve_sweep_zombie` / `self_improve_sweep_zombie_limit` 配置。","32 个新测试覆盖命题核心提取、目标终局、洞见捕获、复评退避、失败冷却、僵尸清扫。","5 条经验已登记进 danao 经验库（note-cfa46344 等），召回验证通过。"]},{"title":"环境依赖型假失败修复（本地绿 / 服务器红）","items":[]}]},{"version":"0.2.0","date":"2026-10-20","summary":"一句话：把“项目里的能力”收敛成可调用的功能总库，把“学到的洞见”接上可复现的验证、漂移监控与回滚，并用一块看板回答“它到底学得怎么样”。","sections":[{"title":"功能总库（Capability Hub）","items":["47 个项目来源、59 项能力、156 个提供方统一成一张目录：公开页 `/capabilities`，管理端「功能总库」可新增/编辑能力与提供方，统一调用生图、生视频、语音、知识、经验。","场景路由与失败治理：缺密钥/缺端点的提供方直接剔除，失败按偏好回退；后台异步视频使用独立 DB 连接，启动时清理 running 孤儿。","成本与素材：按实测 token/次与官方单价记成本台账；素材库配额清理、异盘备份、可下载备份包（tar + manifest + quick_check + 素材数）。","路由规则：经验里的 `provider_note` 可升级为 `route_rule` 并生效，支持项目 + 百分比灰度、批量审批、命中审计、误排除复核、CSV 导出与 CI gate。","质量闭环：提供方成功率/延迟/成本快照、趋势图（SVG/PNG 导出）、质量回写评分、低成功率周报，台账与质量均可按项目过滤。","代码能力库：从项目源码用 AST 抽实现（只读、不执行），生成接口契约与入参，同一能力多份实现按确定性规则打分择优；新增标准实现建议器与实现周报。","单元库 wrapper：库内实现可生成 HTTP wrapper（公开入口自动上移、兼容同级 lib/、含 `-` 目录按路径加载）；实体型入参改为 `{xxx}_id`，未接钩子返回 501 而不猜；生成物走审核流，approve 才落盘。","多镜头叙事成片：逐段生视频 + TTS + 拼接；首帧续接、BGM 混音（`-t` 设时长上限，避免 apad/amix 无限流写爆磁盘）、SRT 字幕、xfade 转场、尺寸归一化。","接入配套：一键接入脚本与 GitHub Actions / GitLab CI 模板。"]},{"title":"技能运行时与路由","items":["技能卡片：从正文确定性解析 purpose / when_to_use / steps / verification / risk / params，不调 LLM；卡片是投影，技能升版后可重建。","路由：name/body 取最大 + 语义混合补召回 + 问句/选择意图加权 + 同版本择优；`skill_route` 返回 confidence 与 hint（低置信先查知识库/经验库）。","调用台账：MCP `skill_outcome` 与 HTTP `/skills/route`、`/skills/outcome` 都写`skill_runs`，跨项目来源、迁移调用与成功率可复算。","评测：normal / hard / fresh50 / dev 四套 held-out 题，每日 cron + 趋势脚本；fresh50 用例做 SHA256 冻结（改题需 `--allow-change`），miss 分类器与近义变体合并。"]},{"title":"自进化引擎（SIE）","items":["能力地图、需求课程、UCB 规划、结算台账四件套；需求来自 `kb_queries.gap`、`failed_check`、`signal` 与真实 `route_feedback`，不编题。","来源级 bandit；`eval_gap` 无 lift 降 reward 并 7 天退避；`route_gap` 阈值 .25 → .35；首次真实流量也能生成需求。","成本感知调度 v1 + 跨项目使用守卫；每日简报与周报加入学习行和路由评测行。","自验证实验闭环：洞见先并入真的会被路由读取的段落，再用 dev(20) + guard(15) 双集复测；只保留可复现的提升，否则恢复正文/版本并重建卡片；台账存改前改后全文，`experiments.py revert --id N` 可一键回退。"]},{"title":"学习质量（R2–R8）","items":["任务结果口径：failed / verified / unverified + 核验强度（有效/证据/存在性），reward 按强度封顶——完成 ≠ 成功。","内容核验 autoverify：只认洞见正文，不认“已学习”计数；token 相关性 + embedding 语义救援（bge-small-zh，阈值 0.50 标定），并保存可复核产物。","可核验补学 relearn：老 learn 题目用新格式重学，带题目质量门、冷却窗、每日预算与独立车道，宁缺毋滥。","失败学习 learnquality：内容核验失败的来源降权，连续失败的题目退避；样本不足时不动，避免把偶发当规律。","跨项目迁移度量：origin、迁移调用、多项目技能、迁移成功率；附业务结果守卫。"]},{"title":"评测漂移与学情看板（R9–R16）","items":["漂移检测：最新一轮 vs 同 suite/mode/cases 前 7 轮中位数；drop ≤ -0.08、warn、unknown 分级，体检新增第 18 项。","慢漂斜率（最近 5 轮线性斜率）与逐题归因（原来命中、现在没命中，最多 10 条）。","门控自动回滚（R11）→ 回滚后观察 recovered / still_dropped（R12）→ 版本级回滚 + 人工队列（R13）。","学情看板（R14）：能力/实验/结果/迁移/漂移/成本/补学七项聚合，人工队列 48h SLA；每日一行快照与“较昨日/趋势”（R15）。","人工队列 webhook（R16）：超 48h/24h 去重推送，成功后写 notified_at，CLI `drift.py notify`。"]},{"title":"经验库与公开页","items":["经验库公开页 `/experience`：分类、检索、项目过滤，JSON / JSONL / Markdown 下载；每条经验有稳定 id 与仓库相对出处。","导出经验包（experience-pack.v1 + cards.jsonl + summary.json + AGENTS-EXPERIENCE.md），其他项目可直接拉取或随仓库携带。","知识库存量扩容：CHANGELOG、git 提交历史、函数 docstring、脚本头注释、`.workbuddy` 记忆入 KB；环境事实按指纹合并；严格召回基准与 IDF 加权。","公开页统一站点外壳 `site.css`；门户首页增加功能总库、经验库入口。","**公开站一致性修复（2026-10-23 晚）**：顶栏改为 `app/web/shell.py` 单真值源，7 个公开页（首页 / 经验库 / 功能总库 / 知识库 / 更新日志 / API 文档 / 管理后台）导航与页脚完全一致；首页不再另写一套“能力/自进化/宪章”锚点导航，锚点收进“本页”行。知识库控制台无 Key 时不再永久“加载中…”，改为明确的未连接状态、可一键导入`.danao_key.txt`、可清除凭据；学情看板改为统一外壳，并把鉴权口径修正为`X-Admin-Token`（原来提示 API Key，实际接口只认管理口令）。回归 `tests/test_site_shell.py` 锁住导航一致、无占位符残留与门禁文案。"]},{"title":"稳定性与运维","items":["`/healthz?fast=1` 跳过内核统计，探针不再因 DB 锁 6s 超时。","`restart_brain.py`：import 预检 → 等在途任务收敛 → 重启 → healthz 轮询；重启前写 5 分钟窗口，避免运维动作被记成 fault episode。","向量增量补齐（按 version 判 stale，不再全量重嵌）；卡片上限 2000 → 5000，新卡自动补向量、退休卡自动清理。","DashScope 视频兼容 `output.video_url`、1920*1080 尺寸；修复合并时短视频被截断、BGM 无限流、1080/1072 尺寸不匹配等问题。","备份三副本与 git bundle 日备；推送失败自动打包 bundle 并重试。"]},{"title":"版本与接口（本版新增）","items":["新增 `app/core/version.py` 作为版本唯一真值源；健康检查、控制台状态、MCP `serverInfo`、`pyproject.toml` 全部读同一版本号。","新增公开接口 `GET /api/version`、`GET /api/changelog` 与公开页 `/changelog`。","升级提示：本次为功能增量，无破坏性变更；旧 API 路径与鉴权方式不变。"]}]},{"version":"0.1.2","date":"2026-10-19","summary":"一句话：补上“学什么、怎么用、有没有用”的控制器与出口，并用验收卡把“完成度”变成硬指标。","sections":[{"title":"本版更新","items":["自进化引擎 SIE 上线：能力地图 + 需求课程 + UCB 规划 + 结算台账，生产跑通多轮。","技能卡片、name-first 路由、`skill_runs` 台账与 held-out 评测上线；MCP 扩到 32 个工具，新增 `skill_route` / `skill_outcome`；gongzuo 服务器版与桌面版完成真实 MCP 调用。","完成度验收卡：8 项硬指标 + 每日 08:20 快照 + 体检监控；旧账与新账分开显示。","方案 B：项目检查 → signal.gate → 独立核验；回填 4,274 条 gate 核验，快探针只跑本地检查。","经验库：CHANGELOG / git 历史 / docstring / 脚本头注释入库，类别视图与信任度排序，人工召回基准、IDF 加权、近重复去重；推送失败自动打包与告警。","运维：服务看门狗、租约回收、重启守卫、探针自污染修复、cron 审计、体检 16/16。","指挥官：统一入口 `commander.py`、每日简报、周报、体检，指标快照与修复前后对比。"]}]},{"version":"0.1.1","date":"2026-10-18","summary":"一句话：接管生产、补上探针与经验库，让“它现在怎么样”有可复查的证据。","sections":[{"title":"本版更新","items":["真实项目探针与 fault episode；L1/L2 自主权边界；证据索引与接管必读。","知识库 W21：docs / repo / corpus / eval 四类来源、混合检索、训练导出、MCP/CLI、定时刷新与无外网 bundle 导入。","项目经验库 v1：扫描各项目 AGENTS/CLAUDE/docs/日志，抽规则、坑、环境事实与故障模板，开工前 `load <项目>` 先读坑。","OpenAI 兼容 `/v1` 与 MCP `/mcp` 接入层；API key scope 与审计。","服务器迁移：150.138.73.16 → 202.189.22.187；配置与密钥分离，仓库不含凭据。"]}]}]}