Skip to content

merge - #22

Merged
mambo-wang merged 101 commits into
mainfrom
develop
Sep 6, 2026
Merged

merge#22
mambo-wang merged 101 commits into
mainfrom
develop

Conversation

@mambo-wang

Copy link
Copy Markdown
Owner

No description provided.

mambo-wang and others added 30 commits August 29, 2026 00:53
grilling 收敛的设计方案(docs/)、to-spec 产出的实现规格与
to-tickets 拆分的十张工单(.scratch/centralized-wiki-layout/)。
工单 01(prefactor):wiki_index 内联的追加锁抽取为可复用的读改写锁
原语(src/locks.py),线程层 + OS 层(fcntl/msvcrt)双层;句柄即锁柄,
规避 Windows LockFile 拦截同进程其他句柄;加锁失败保持旧版"降级仍写"
语义,纯 prefactor 零行为变化。

工单 02(奠基):
- init_workspace 增 layout 参数(colocated 默认=现状逐字节一致;
  centralized 写 .meta/workspace.json,拒绝就地换布局,拒绝自定义
  output_dir——探测锚定在 <workspace>/repowiki);registry inputSchema
  同步接线;
- 新模块 workspace_layout:唯一路由接缝,探测只认 workspace.json、
  成员校验(登记表公共函数)、三态回退、进程内缓存,护栏覆盖单库零
  影响与未登记目录防劫持;
- AGENTS.md 约定块按布局生成变体(新增集中式模板,锚点/refresh 语义
  不变)。

测试:新增 23 项(锁并发含多进程 + 解析护栏 + init 布局),schema 钉
固测试更新;全套 493 通过。评审修复:配置读取去重、公共登记表函数、
魔法字符串常量化、next_steps 收敛。
集中模式下登记业务仓:建 repowiki/wiki/modules/<名>/ 分区骨架(含
.gitkeep)、repo-map 用集中变体(分区路径 + repo= 一跳检索)、不在业
务仓内建任何知识库目录,并移除业务仓 AGENTS.md 中指向不存在的仓内
知识库的 CodeWiki 块(其余内容保留;文件只剩空壳时删除)。colocated
行为逐字节不变。新增 remove_codewiki_block 与 4 项测试。
写入接缝统一走 workspace_layout:
- default_output_dir:集中模式成员仓 → 工作区知识库,其余现状;
- routing_for_write:输出目录与仓身份双重校验后返回分区仓名;
- resolve_doc_path 增 repo_name:module 页 → wiki/modules/<仓>/ 分区,
  共享池页型不分区(schema 保持布局无关,分区是路由层职责);
- write_doc_file:共享池页自动打来源标、后写覆盖(读改写临界区由工单
  01 锁原语保护,来源只增不减);module 页保留"已存在报错"语义;
- ingest_note:笔记落工作区 notes/ 并带 metadata.repo 来源标;
- analyze_repo:默认 output_dir 布局感知;project.json 的 cache_db 改为
  相对 output_dir.parent 的可移植路径(标准布局逐字节不变)。

测试:新增 21 项(路由接缝、来源累积、分区、并发写不丢来源、
write/ingest 集成、colocated 回归);全套 518 通过。
- repo_path 回退布局感知:集中模式成员仓默认查工作区知识库(一跳覆盖
  产品级+全部业务仓);
- 新增可选 repo= 过滤:命中"适用于该仓的知识"=该仓 modules 分区 ∪ 带该
  仓来源标的共享页 ∪ 无标全局页;其他仓分区与其他仓专属页排除;
- 过滤仅在集中式语料库内生效(is_centralized_corpus 门控),单库与
  colocated 查询不受任何影响(registry 契约);
- 过滤前按 3 倍预算多取候选再截断,保证选择性范围仍能填满 max_results;
- 与 output_dir 组合时:output_dir 选语料库、repo= 在其内收窄;
- registry inputSchema 接线,响应透传生效中的 repo_filter。

测试:新增 8 项(三态并集、负例排除、幽灵仓只剩全局、分区语料库、
非集中语料库完全无效、一跳默认);knowledge_loop 关联回归 137 项全绿。
- 新增 parse_scope_arg:scope 参数归一为 None(自动)|"global"|仓名列表
  (支持列表/单名/逗号分隔字符串);
- write_doc_file / ingest_note 支持显式 scope:缺省自动打写入仓来源标;
  "global" 写产品线知识不打标;列表精确写 repos: [...];
- merge_provenance 增 explicit_scope:显式重定范围精确替换(全局清除、
  列表精确),缺省维持"来源只增不减"累积语义(D9);
- registry 两工具 schema 接线。

测试:新增 19 项(解析、全局清除、精确设置、覆盖重定范围、默认累积、
端到端 repo= 过滤命中);全绿。
任务记忆、对话采集/蒸馏、会话关闭、外部文档导入的 repo_path 回退统一
改走布局感知的 default_output_dir:集中模式成员仓的 tasks/、raw/、
conversations/、.meta 绑定一律落工作区根共享区(不按仓分片——任务与会话
天然是工作区尺度);colocated 与单库保持 <repo>/repowiki 现状。task_manager
经由共享的 _resolve_output_dir 自动继承。写入格式、原子追加与时间戳头解析
边界逐字节不变(ADR-0001/0002),只有根移动。

测试:新增 6 项(解析、采集落点、任务记忆全流程含格式断言、双布局对照);
对话/任务链路既有回归 118 项全绿。
- 布局探测:集中模式下逐仓分析目标改为工作区知识库,不再硬编码
  <仓>/repowiki;has_overview 检查分区位置;
- 新增 generate_repo_wikis(默认 false):集中模式下重的逐仓分析受其
  门控,关闭时仍产出总览与跨服务元数据(读各仓既有分析缓存,布局无
  关,优雅降级);开启后逐仓填充分析态;
- colocated 行为逐字节不变、开关被忽略(响应置 None);
- 响应透传 layout 与 generate_repo_wikis;registry schema 接线。

测试:新增 4 项(拓扑单跑、生成填充、生成后拓扑重跑、colocated 对照)。
新增 layout_violations 检查(仅集中式语料库内生效,is_centralized_corpus
门控,其余布局零触发):
- 业务仓目录出现 repowiki/(知识回流)→ warning,附合并回工作区的修复建议;
- 共享池页缺 repo:/repos: 来源标 → info 提示(无标=全局本身合法,此检查
  的真实职责是让 remove_workspace_repo 解除唯一来源后产生的孤儿页浮出
  来交人工裁决);模块分区豁免——位置即来源。
lint 的 repo_path 回退同步布局感知;_ALL_CHECKS 与 registry 枚举接线。

测试:新增 5 项(合规零报、回流告警、孤儿提示、多仓标通过、非集中完全
惰性);既有 lint 回归全绿。
集中模式下移除业务仓不留知识孤儿:
- 删除该仓 modules 分区(harness git 追踪,可从版本控制恢复);
- 共享池来源清理在文件锁内逐页读改写:多来源页只移除该仓,唯一来源页
  保留内容、解除标注成为孤儿——由 lint layout_violations 的"缺来源标"
  规则浮出交人工裁决,知识永不自动删除;
- 清理计数(分区/更新/孤儿)并入响应;
- colocated 无共享知识可清,行为不变;未登记 name 仍为安全错误。

测试:新增 5 项(全量清理、孤儿被 lint 浮出、移除后检索态、colocated
对照、未登记安全错误)。
全量 565 通过 / 2 跳过 / 0 失败(基线 470 → 净增 95 项测试);
报告含工单覆盖矩阵、验收核对、质量门、已知限制与提交清单。
- init_workspace 移除 workspace_path/layout/refresh_conventions/with_readme 参数,
  只留 output_dir;重跑自动沿用布局、强制刷新约定块、自动克隆登记表业务仓
- remove_workspace_repo 默认删除目录,并清理 analyze_workspace 产生的
  跨仓分析缓存(workspace_routes/cross_service_links/infra_services/overview.md)
- infra_scanner 支持按仓归属过滤(source_path),适配跨仓缓存清理
- server.py 增加进程生命周期诊断(faulthandler/signal/atexit hooks),
  排查 MCP 服务器静默退出问题
- 同步更新文档与测试
- _write_text 对 .ps1 改用 utf-8-sig(.sh 保持无 BOM 以免破坏 shebang)
- _read_text 改用 utf-8-sig 读取,重写时不会叠加双 BOM
- init_workspace 重跑时对存量无 BOM 的 bootstrap.ps1 字节级自愈
- 新增 3 个回归测试;归档 pitfall 笔记到 repowiki/notes
- 首次初始化(骨架不齐备+无持久化配置+未传 layout)不写任何产物,返回
  needs_layout_decision 与两选项,由调用方 Agent 征询用户后带 layout 重调;
  重跑(有配置/存量无配置)豁免闸门
- workspace.json 两种布局都持久化(反转仅集中式写入的旧约定);
  clone-only 接管为无配置的存量工作区补写(backfilled)
- layout 重回 MCP schema(enum),工具描述与 init-workspace prompt 同步;
  修 prompt 分支顺序歧义(全新目录先于"骨架有缺失"判定)
- 测试:新增 TestLayoutDecisionGate×5,_init 辅助默认 layout,
  存量用例适配;全量 590 过、ruff 通过
- 文档:管理模型 §4.1/§5、README 中英文工具表与 prompt 表同步
- cache: 新增 default_cache_db(),centralized 成员仓分析缓存移至 <ws>/.codewiki/<repo>/analysis_cache.db
- workspace: centralized 成员仓 session workspace 移至 <ws>/.codewiki/<repo>/workspace,不污染业务仓
- analysis: 用 default_cache_db() 计算 cache_db 相对路径
- prompts: 修正 init_workspace/add_workspace_repo 提示——centralized 下 init_wiki 不适用于仓库级,明确 analyze_repo(单仓) 与 analyze_workspace(跨仓) 分工
- cache.py 新缝 analysis_meta_dir/resolve_analysis_meta_file:centralized 成员仓
  metadata/module_tree 落 <ws>/.codewiki/<仓名>/(与 SQLite 缓存命名空间合一),
  colocated 保持 output_dir/.meta,旧单文件回退读
- analyze_repo 7c 无锚点时建基线(commit_id=HEAD);close_session、
  _detect_doc_changes、module_tree 读写点同步切换
- workspace_analyzer per-repo 三档分派(skipped/incremental/full)+ centralized
  首跑 deferred 闸门;skipped 复用 summary stats;untracked 噪音过滤
  (仓内 repowiki/.codewiki 不算脏);changes/affected_modules 透传
- 修 module_tree 结果嵌 Path 致 JSON 序列化失败;修 b792349 过期断言
- 同步 registry 描述/README 中英/管理模型;新增增量更新设计方案文档;
  TestIncrementalDispatch×5
- 绝对路径提交后队友克隆到其他目录即失效,$*_PROJECT_DIR 变量展开经实测
  不可靠,改为相对路径(宿主以项目根为工作目录执行命令)
- 重跑接线时旧格式条目(绝对路径/反斜杠/环境变量占位符)原地迁移,
  保留原 timeout、不产生重复注册
- 新增 Gemini CLI(.gemini)接线支持,自动检测一并覆盖
- hook 脚本 REPO 解析补充 QODER/GEMINI/TRAE_PROJECT_DIR 进程级回退
- 同步 init-wiki / team-memory-hook prompt 接线指引与文档,新增迁移测试
- claude 家族(Qoder/Claude Code/Gemini CLI)解析 CodeBuddy 专属
  frontmatter(tools: ReadFile / toolsMCP)得到空工具集,subagent
  报 "resolved tool set is empty" 不可用
- 新增 codewiki/agents/distill-worker.claude.md(claude 家族
  frontmatter 与工具名);安装按 IDE_SPECS.agent_file 选源变体,
  目标文件名保持 distill-worker.md,变体缺失回退默认源
- 新增 5 个接线测试(变体分发/默认保持/缺失回退),同步本仓
  .qoder 接线;宿主注册表为会话启动快照,需新会话验证生效
- 蒸馏 3 条积压对话并确认 7 条笔记(6 条任务/通用经验 + 1 条
  多宿主 frontmatter 分发教训),原对话归档 conversations/
- consolidate_notes 吸收 34 条笔记进 8 个场景块(新增:代码评审
  与分析工具方法、多仓工作区初始化与增量分析),聚合计数归零
- Doctrine 刷新并确认(新增增量锚点复用、多宿主分发变体规则)
- 任务记忆、遥测与检索索引同步(会话绑定为活跃会话临时态,不入库)
- 新会话实测:显式枚举 tools: Read, Write, mcp__<server>__<tool> 时
  内置工具可解析、但 mcp__ 限定名不透传给子代理,Mode C 不可行
- 省略 tools 行(claude 家族缺省语义=继承全部工具)后 spawn 正常、
  内置工具与 MCP 元工具齐备;ide_config 注释记录实测依据
热点定向(近 60 提交)+ 三路并行探索结论:
- #1 拆 knowledge_loop(Strong)
- #2 抽检索 kernel src/retrieval.py(Strong,首选,4 phase 已定稿)
- #3 frontmatter 读写一体层(Strong,P1-2 前置)
- #4 store.py 唯一写路径(Worth exploring,修 task_manager 无锁竞态)
- #5 共享 helper 落座 store_bridge(Speculative,搭 #1 车)
固定 fixture wiki(notes/wiki/scenarios/ontology/schema),SQLite 与
legacy JSON 双路径 20 个查询快照(top-k 顺序、分数、authority、usage、
est_tokens),record/diff 双模式供后续每个 phase 逐字段对比。
基线:pytest 772 通过 1 skip;okf_regression 99 通过 3 存量失败。
…e 1)

move, not copy:tokenize/snippet/ontology/authority/usage_heat/indexable_text
逐字搬移,私有名经模块尾别名转正为公开接口(tokenize/STOPWORDS/K1/B…)。
cache.py 留过渡 re-export shim;wiki_search 与 knowledge_loop 的
from codewiki.mcp.cache import _(11 处私有 import)全部改指 kernel 正主。

golden 零漂移;pytest 772 通过;okf_regression 99 通过 3 存量失败(与基线一致)。
…入口(Phase 2)

- SearchIndex Protocol(build/search/update_file):SQLite 与 legacy JSON
  两 adapter 的 interface 正式化,seam 唯一所有者为 wiki_search.search
- _ensure_index 成为唯一 freshness gate(build-if-missing / 三级 stale
  check),原先在 query_wiki 两个 handler 调用点 + search() sessionless
  分支的三处重复全部删除——handler、distill 去重召回、by_file 预检
  免费获得 freshness(60s 节流不变)
- update_file 的 built_at 刷新注释从"手抄 mirror"改为 JSON adapter
  自有基线责任(invariant 藏到 seam 后面)
- golden 再基线化:SQLite 快照逐字节不变;JSON 路径从空结果变为与
  SQLite 排序完全一致(0 跨 adapter 不匹配)——预期行为改进非漂移
- _extract_frontmatter_block(12 个调用点,含 review_changes 跨模块
  import)改为对 src/frontmatter.parse_frontmatter 的薄委托——读侧
  统一到一个 parser,yaml 依赖从该路径移除
- 升级 _parse_block:"- key: value" 映射项 + 深缩进续行解析为 dict
  (OKF §5 verified: [{by, at}] 是正主写侧形态,此前被折叠成字符串
  导致晋升年龄回退失效)——新 _KEY_VAL_RE 保证裸 key 才进 dict 分支,
  引号包裹含冒号的 item 仍是字符串
- golden 零漂移;pytest 772 通过;okf_regression 99 通过 3 存量失败
- cache.py 内部 ~30 处 _tokenize/_doc_authority/… 改用 kernel 公开名,
  局部 _K1/_B 定义删除(kernel 是唯一来源)
- 测试的 kernel 私有 import(test_authority_p0/test_adoption)改指
  src/retrieval;from codewiki.mcp.cache import <kernel 私有名> 全仓归零
- cache.py 瘦身至纯 persistence adapter:SQLite schema/路由/指纹/索引
  存储 + AnalysisCache,文本逻辑全部在 kernel

golden 零漂移;pytest 772 通过;okf_regression 与基线一致。
检索 kernel 重构(候选 #2)四阶段完成。
- src/frontmatter.py 补 render_frontmatter:标量/标量列表/嵌套映射/
  映射列表(verified 形态)全形状序列化;parse(render(x)) == x 往返
  不变量以 7 项测试固化(含中文/特殊字符/YAML 保留字/status 与
  task_id 顶层单行永久约束——stdlib hook 兼容)
- reader 能力补齐:YAML 流式集合 tags: [a, b] / generated: { by: x }
  解析为 list/dict,与被替换的 yaml 语义对齐(_split_flow 深度感知
  逗号分割 + _has_flow_noise 逃生口)
- 读副本收口(第 3/4/5 份):distill._parse_frontmatter、
  wiki_search._extract_fm、retrieval._parse_frontmatter_dict 全部改为
  对 src/frontmatter.parse_frontmatter 的薄委托;distill 的 _unquote_fm
  降级为兼容垫片
- 修复搬移事故:正则替换吞掉 _ontology_cache 模块级定义,golden
  抓回(ontology 展开失效导致 6 快照分数漂移)——基线闸门的第一次
  实战

golden 零漂移;pytest 779 通过;okf_regression 与基线一致。
- 删 task_manager._atomic_replace_with_retry(与 store.py:79 逐字重复)
- 压缩归档写入改 locked_rmw(append 语义不变),修复同用户双进程
  压缩竞态窗口;own 文件重写改 locked_write
- 四颗卫星本地原子写(aggregation_state / page_manifest /
  wiki_search._save_index / doctrine)改走 store.atomic_write——
  同一 temp+replace 惯用法五份代码归一,pid+tid 命名与清理语义
  由漏斗统一保证

golden 零漂移;pytest 779 通过;okf_regression 与基线一致。
CONTEXT.md 新增 retrieval kernel / SearchIndex adapter 词条;
frontmatter module 词条从"只有读路径"更新为读写一体(render_frontmatter
+ 往返不变量 + 流式集合吸收)。评审清单标注 #2/#3/#4 已完成、#1 待做,
记录 golden 基线的实战战果(抓回 _ontology_cache 搬移事故)。
- pending_raws_by_task 正主从 capture_conversation 迁入 store_bridge
  (本就是 KnowledgeStore 薄转发)——task_manager 与 distill 停止
  import 兄弟模块私有名
- task_manager 的 _resolve_output_dir/_slugify 改指 store_bridge 与
  store.slugify 正主
- knowledge_loop._slugify 保持不动:与 store.slugify 语义不同
  (CJK 标题 hash 回退 vs 返回空串),是 ingest 文件名约定,随
  ingest 模块搬迁(见候选 #1
2,947 行单文件按工具族拆分(locality:一族一文件):
- note_ingest.py(472)— handle_ingest_note + 模块自匹配/标签/符号链接
- note_lifecycle.py(305)— confirm/reject/batch_set_status + 文档清单迭代
- note_query.py(1,416)— query_wiki 五模式 + legacy 关键词回退
- wiki_stats.py(341)— handle_wiki_stats + cold/promotion 候选
- note_freshness.py(244)— stale_after 窗口评估引擎
- note_writer.py(360)— NoteWriter deep module:文件名 slug(CJK hash
  回退约定)、锁内 status 改写(verified 追加/stale_after 续期)、
  refresh_note_indexes 写后刷新序列(从 ingest 内联副本抽出)
- knowledge_loop.py 降为兼容 facade(20+ 测试与兄弟模块的 import 面
  不变);registry 六个 handler 路径改指真实 module(48 工具全注册)
- 分层无环:writer → freshness → ingest → lifecycle → query → stats

golden 零漂移;pytest 779 通过;smoke 132 通过;okf_regression 与基线
一致(99/3 存量)。legacy 关键词回退路径与基线行为逐点核对一致。
索引→目录卡片、遥测→记账、幂等键→防重复编号、原子替换→临时文件
顶替等术语首次出现即给出白话解释;长句拆短、被动改主动;抽象规则
补人话注解("文件所有权就是锁"→"文件归谁,谁才有笔")。全部数字与
技术事实与代码核对过;第十节"并行的另一条线"更新为已落地。
- init_wiki/schema_generator 移除根目录 schema.yaml fallback,模板 codewiki/templates/schema.yaml 为唯一事实源
- 删除仓库根 schema.yaml,tests/test_promotion 同步校验包内模板
- templates/repowiki schema.yaml 新增 auto_evidence 约定(模块文档自动打代码证据 content_hash)
- wiki_index: frontmatter description 内相对链接移入 index.md 时补页面目录前缀,消除 lint stale_refs 误报(URL/anchor/绝对路径不动)
- 新增 tests/test_index_summary_links 覆盖重定位与豁免场景
- patterns: 依赖分析忽略 .caveman-tmp/.qoder/.workbuddy 等 agent 临时工作区,避免把第三方仓库源码当项目源解析
- 新增 wiki/modules/KnowledgeStore.md、MCP_Tools_Workspace.md;多模块页补页(AnalyzerUtils/LLM_Backend/DocWriter/Knowledge/Quality)
- 新增 2026-09-04 caveman 技能生效机制与 agent-hook 注入工程化笔记、conversation 存档
- reading-guide/log/index 索引与 page_manifest 等元数据同步更新
- README 补第 9 篇多仓 Harness 集中式管理文章链接
- 公众号版(docs/articles/):机器写的Wiki凭什么可信——证据、保鲜与冲突消解
- 技术版(docs/):含源码引用块,面向开发者与智能体,附精确 file:line 定位
- source_ingest: name 已被登记且内容不同时返回 conflict,不静默覆盖;overwrite=true(用户同意)后旧 raw 文件移入 .trash 再落新文件
- registry: ingest_source 增 overwrite 参数与冲突语义描述;query_wiki 等支持 repo_path
- store_bridge: resolve_output_dir 错误提示补充 repo_path/output_dir 用法
- tests: 新增同名冲突/overwrite 回归用例与 target anchor 防护测试
query_wiki mode=check and distill_conversation's dedup consumed search
results (and notes/*.md) without the lifecycle skip rule that the default
BM25 and by_file paths already apply. A retired note — status deprecated, or
legacy rejected/superseded normalized by _norm_status — could therefore win
the "does this already exist?" judgment: a fresh draft was merged into (or
suppressed by) dead knowledge, and a relevance pre-check reported a hit that
is not knowledge.

Both sides now share one rule:
- note_query._note_lifecycle_status() — read paths (mode=check joins the
  default BM25 and by_file paths); non-note hits return "" unchanged.
- distill_conversation._is_retired_note() — strong dedup merge target,
  title-sim weak band, BM25 recall band.

The search kernel is deliberately untouched: superseded_by tracing and draft
annotation depend on seeing the raw hits.

Verified with a two-fixture probe (stable+deprecated+superseded, and
deprecated-only). Before: every consumer surfaced retired notes, and the
deprecated-only fixture resolved its merge target to a deprecated note.
After: the mixed fixture resolves to the stable note; the deprecated-only
fixture resolves to None with empty conflict/recall/result sets. 91 tests
across the distill, query, authority and claude-mem suites pass.
- ingest_note: 鍐欏墠 similar_notes 鍐茬獊鎵弿 (detect_conflicts, 榛樿 true)锛屼笉鑷姩瑕嗙洊/鍚堝苟锛岄€€褰圭敱璋冪敤鏂瑰喅绛?- ingest_source: 鏂囨湰鏂囨。鏂板 version_sibling / supersede_declared 鐗堟湰闂ㄦ帶锛宎llow_sibling 浣滀负鐢ㄦ埛鍚屾剰浠ょ墝
- distill_conversation: 寮卞啿绐佹娴嬮噸鏋勪负 _find_conflict_candidates (鏀寔寮哄啿绐佸甫 include_strong)
- 鏂板 codewiki/src/doc_similarity.py: 鏂囨湰鎸囩汗/鍏变韩鏍囬鐩镐技搴?- AGENTS.md / agents_md / query_wiki adoption_hint: 鏄惧紡鏍囨敞渚濇嵁绾﹀畾 (渚濇嵁:<file> / <code>:<line>)
- 鏂板娴嬭瘯 tests/test_ingest_conflict_advisory.py锛屾墿灞?tests/okf_regression_test.py
- wiki 鐢熼暱: 绗旇/瀵硅瘽/wiki 椤甸潰/浠诲姟璁板繂/page_manifest 鏇存柊
@mambo-wang
mambo-wang merged commit 438f6fb into main Sep 6, 2026
2 checks passed
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.

2 participants