fix(session-mechanism): 常驻读不到宿主库 ⇒ 检查会话永不建

- init_workspace.py 生成配置时写 host_db(宿主 env → 本包 env/roots.env);旧配置留空则补,已写值不动
- collabd._wb_db() 去掉 ~/.workbuddy 回落(本机无此文件),取不到改为占位路径 + 限流留痕
- _sm_load_roots() 先读 COLLABD_CONFIG 所指配置的 host_db,再试 <CODEBUDDY_CONFIG_DIR>/skills/session-mechanism/env/roots.env,最后才上跳
- pitfalls 新增 P0-99(含「新工作区验收跑一次脱环境探针」通则)

实测:deepwrite-harness 新建区 2091 条「读库失败」、11.5 小时零检查会话;修复后五区重启读库失败归零,检查会话建棒并把目标置「已完成」
This commit is contained in:
admin committed 2026-10-17 11:36:13 +08:00
1 parent 8160f91559
commit 310a964a94
3 files changed
+111 -3

No files matched your search

+57 -3
View File
@@ -70,6 +70,21 @@ from __future__ import annotations
def _sm_load_roots():
import os as _os
_here = _os.path.dirname(_os.path.abspath(__file__))
# 🔴🔴 2026-10-17 补:**先读本区部署配置的 `host_db`**(最接近真相的一条)
# 启动器恒会设 `COLLABD_CONFIG`;配置里那项是 `init_workspace` 按本机写下的绝对路径。
# 为什么排第一:工作区副本与技能包没有相对关系 ⇒ 上跳找 `env/roots.env` 恒落空
# ⇒ 只靠上跳,常驻的 `CODEBUDDY_CONFIG_DIR` 永远为空 ⇒ 宿主库路径解析失败
# (deepwrite-harness 实测 2091 条读库失败、检查会话整夜不建)。
_cfgp = _os.environ.get("COLLABD_CONFIG") or ""
if _cfgp and _os.path.isfile(_cfgp):
try:
import json as _json
_hd = (_json.load(open(_cfgp, encoding="utf-8")).get("host_db") or "").strip()
if _hd:
_os.environ.setdefault(
"CODEBUDDY_CONFIG_DIR", _os.path.dirname(_os.path.normpath(_hd)))
except Exception:
pass
# 🔴 2026-10-11:「脚本是脚本 配置是配置」⇒ 配置落本包 `env/`。
# 首选 `env/roots.env`;并兼容旧的包根 `roots.env`(拷贝未同步时照旧能跑)。
for _up in range(4):
@@ -87,6 +102,30 @@ def _sm_load_roots():
except Exception:
pass
return
# 🔴🔴 2026-10-17 补第三路(实测:工作区副本这条路恒落空)
# 副本住在 `<工作区>/.workbuddy/collab/`,与技能包没有相对关系 ⇒
# 「从自身位置往上跳」永远跳不到 `<技能根>/session-mechanism/env/roots.env`
# ⇒ `CODEBUDDY_CONFIG_DIR` 一直为空 ⇒ 宿主库路径解析失败
# (deepwrite-harness 实测 2091 条读库失败,检查会话整夜不建)。
# 技能根的位置只能由配置目录推出来:`<CODEBUDDY_CONFIG_DIR>/skills/session-mechanism/`。
_cfgdir = (_os.environ.get("CODEBUDDY_CONFIG_DIR")
or _os.path.expanduser("~/.workbuddy")).strip()
for _cand in (
_os.path.join(_cfgdir, "skills", "session-mechanism", "env", "roots.env"),
_os.path.join(_cfgdir, "skills", "session-mechanism", "roots.env"),
):
if not _os.path.isfile(_cand):
continue
try:
with open(_cand, encoding="utf-8", errors="replace") as _f:
for _ln in _f:
_ln = _ln.strip()
if _ln and not _ln.startswith("#") and "=" in _ln:
_k, _v = _ln.split("=", 1)
_os.environ.setdefault(_k.strip(), _v.strip())
except Exception:
pass
return
_sm_load_roots()
# 🔴 2026-10-01 加 · **输出编码兜底**:脚本一旦被重定向(钩子/常驻/后台任务都会这么干),
# Windows 本地编码(GBK)编不出 ⛔/✅/🔴 这类字符 ⇒ `print` 抛 UnicodeEncodeError
@@ -3761,9 +3800,24 @@ _LIFE_ALIAS_WAIT_NOTE = "等待" # 旧值显示用的兜底文案
# v3 补 runtime_state → 仍未拾取(证明那行没用)
# v4 两项都对 → IN_PROGRESS + 真实 conversationId
def _wb_db() -> Path:
"""宿主活动库(⛔ **不是** `~/.workbuddy/workbuddy.db` —— 那是旧库且可能是 0 字节空文件)。"""
cfg = os.environ.get("CODEBUDDY_CONFIG_DIR") or ""
return Path(cfg) / "workbuddy.db" if cfg else Path.home() / ".workbuddy" / "workbuddy.db"
"""宿主活动库(⛔ **不是** `~/.workbuddy/workbuddy.db` —— 那是旧库且可能是 0 字节空文件)。
🔴 2026-10-17 改:**取不到配置目录 ⇒ 返回一个不存在的占位路径 + 留痕**。
原先是回落 `Path.home()/".workbuddy"`,本机该文件不存在(或 0 字节空库)⇒
报出来是 `unable to open database file`,与「真的没有会话」在日志里分不开
(deepwrite-harness 实测 2091 条,整夜锁死闸② ⇒ 检查会话一个都不建)。
留痕用 `log_throttled`:同一原因 10 分钟一条,⛔ 不刷屏。
"""
cfg = (os.environ.get("CODEBUDDY_CONFIG_DIR") or "").strip()
if cfg:
return Path(cfg) / "workbuddy.db"
try:
log_throttled("wb-db-unresolved", 600,
"宿主库路径未解析:CODEBUDDY_CONFIG_DIR 为空、本区配置也没给 host_db "
"⇒ 检查会话建不出来(查启动器三级兜底)")
except Exception:
pass
return Path("__unresolved_config_dir__") / "workbuddy.db"
def _ro_conn():