feat(memcore): 三项优化——等价表述清单、即时引用快扫、并发写入冲突保护
- memory-lint: 新增 Phase 4-pre 等价表述加载(synonyms.md),矛盾检测先过等价组 再判断,降低 AI 语义误判率;幽灵检测排除 synonyms.md;合并残留标记 (<!-- merge-conflict --> / <!-- remote-diverge -->) 纳入 Phase 4 NEED-HUMAN 检测; Phase 9 独立输出增加 synonyms.md 创建提示 - memory-update: synthesis 双触发升级为三触发,新增 Phase 3C 即时引用计数快扫, 每次执行末尾强制扫描,不依赖 lint 延迟触发,短会话也能捕获升级候选 - memory-sync: Phase 0 重构为"冲突优先检测 → 普通变更提交"两步结构, 冲突语义合并规则补齐 user_profile/synthesis_* 保护边界;Phase 3 新增并发分歧 检测(mtime 差 <7 天),对双边改动文件执行轻量节段合并;Phase 11 报告加入 并发冲突处理摘要行;流程概述、执行约束同步更新 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
9c2f19b579
commit
f26e741b0e
@@ -49,7 +49,7 @@ ls "$PROJECT_DIR/.claude/memory/"*.md
|
||||
| Phase | 定义 | 级别 | AUTO-FIX |
|
||||
|-------|------|------|---------|
|
||||
| 1 孤儿 | 索引有 → 磁盘无 | ERROR | 从 MEMORY.md 删该条目 |
|
||||
| 2 幽灵 | 磁盘有 → 索引无(排除 MEMORY.md / lint_report.md) | WARN | 补入索引(类型推断见下) |
|
||||
| 2 幽灵 | 磁盘有 → 索引无(排除 MEMORY.md / lint_report.md / synonyms.md) | WARN | 补入索引(类型推断见下) |
|
||||
|
||||
幽灵类型推断:`user_*` → user / `project_*` 或 `decisions.md` → project / `feedback*` → feedback / `reference*` → reference / `synthesis_*` → synthesis / 其他默认 project。
|
||||
|
||||
@@ -84,6 +84,40 @@ ls "$PROJECT_DIR/.claude/memory/"*.md
|
||||
|
||||
三类全部为 NEED-HUMAN,写入 lint_report.md 时**必须附带 3 问 yes/no checklist + 决策矩阵**(Phase 8 模板)。
|
||||
|
||||
### Phase 4-pre — 等价表述加载
|
||||
|
||||
矛盾检测前先加载 `$PROJECT_DIR/.claude/memory/synonyms.md`(可选文件)。
|
||||
|
||||
**加载方式**:
|
||||
```bash
|
||||
[ -f "$PROJECT_DIR/.claude/memory/synonyms.md" ] && \
|
||||
grep -v "^#\|^---\|^$\|^name:\|^description:\|^type:" \
|
||||
"$PROJECT_DIR/.claude/memory/synonyms.md"
|
||||
# 输出每行一个等价组(逗号分隔),大小写不敏感,存入 $SYNONYMS_GROUPS
|
||||
```
|
||||
|
||||
**synonyms.md 格式**(用户自行在项目内创建和维护):
|
||||
```markdown
|
||||
---
|
||||
name: 等价表述清单
|
||||
description: 矛盾检测等价词表,同组词视为相同概念
|
||||
type: reference
|
||||
---
|
||||
|
||||
# 等价表述清单
|
||||
> 每行一组,逗号分隔,大小写不敏感
|
||||
|
||||
PostgreSQL, PG, Postgres, postgresql
|
||||
JWT, JSON Web Token
|
||||
Vue3, Vue 3, Vue 3.x
|
||||
```
|
||||
|
||||
**判定规则**:检查两处描述中出现的技术术语是否属于同一等价组。若属同组 → 跳过,不纳入矛盾候选。
|
||||
|
||||
**无 synonyms.md 时**:仅检测直接数值/版本冲突(如 PostgreSQL 14 vs PostgreSQL 16),对措辞差异不报告。
|
||||
|
||||
---
|
||||
|
||||
### Phase 4 内容矛盾
|
||||
|
||||
| 维度 | 检查 |
|
||||
@@ -92,6 +126,25 @@ ls "$PROJECT_DIR/.claude/memory/"*.md
|
||||
| decisions vs 架构文件 | 与 pom.xml / package.json / requirements.txt 实际依赖不一致 |
|
||||
| 多 feedback 文件 | feedback.md 与 feedback_{topic}.md 重复或矛盾 |
|
||||
| synthesis vs decisions | synthesis 结论与决策抵触 |
|
||||
| 合并残留标记 | 文件含 `<!-- merge-conflict -->` 或 `<!-- remote-diverge -->` → WARN,NEED-HUMAN |
|
||||
|
||||
```bash
|
||||
grep -rn "<!-- merge-conflict\|<!-- remote-diverge" "$PROJECT_DIR/.claude/memory/" --include="*.md"
|
||||
```
|
||||
|
||||
合并标记的 NEED-HUMAN 条目模板:
|
||||
- **位置**:`decisions.md → ## [合并待审] JWT 密钥安全`(`<!-- merge-conflict: 2026-05-10 -->`)
|
||||
- **Checklist**:Q1 本地版本是否正确?Q2 远端版本是否有本地没有的有效信息?Q3 是否可合并为单一表述?
|
||||
- **矩阵**:Q2 否 → 删除 `## [合并待审]` 段落和标记;Q2 是 + Q3 是 → 合并后删标记;Q3 否 → 保留两段但清除 HTML 注释
|
||||
|
||||
矛盾判定门槛(过 synonyms.md 等价检查后):
|
||||
|
||||
| 情况 | 处理 |
|
||||
|------|------|
|
||||
| 同主题,等价组内术语不同 | 跳过,不报告 |
|
||||
| 同主题,结论相反(推荐 A vs 推荐 B) | WARN → NEED-HUMAN |
|
||||
| 同主题,数值/版本直接冲突 | ERROR → NEED-HUMAN |
|
||||
| 措辞不同,无直接逻辑冲突 | 跳过(宁漏报不误报) |
|
||||
|
||||
```bash
|
||||
cat "$PROJECT_DIR/pom.xml" || cat "$PROJECT_DIR/package.json" || cat "$PROJECT_DIR/requirements.txt"
|
||||
@@ -226,6 +279,11 @@ last_updated: YYYY-MM-DD
|
||||
|
||||
独立调用:扩展输出已修复 / 待处理清单 + 报告路径;全通过则 `✅ 记忆体系健康,已更新执行时间`。
|
||||
|
||||
发现矛盾候选且 `synonyms.md` 不存在时,额外输出:
|
||||
```
|
||||
💡 创建 .claude/memory/synonyms.md 可将等价术语(如 "PostgreSQL, PG")预先排除出矛盾检测,降低误报率。
|
||||
```
|
||||
|
||||
每次执行必须更新 lint_report.md(即使全通过也刷新执行时间)。
|
||||
|
||||
---
|
||||
@@ -234,6 +292,6 @@ last_updated: YYYY-MM-DD
|
||||
|
||||
1. **AUTO-FIX 边界严格** — 只修结构性错误(孤儿、幽灵、断链、双链),不改业务内容
|
||||
2. **NEED-HUMAN 完整记录** — 每项含 checklist + 决策矩阵
|
||||
3. **矛盾检测宁缺勿滥** — 措辞不一致 ≠ 矛盾,宁漏报不误报
|
||||
3. **矛盾检测先过等价表** — 先加载 `synonyms.md` 再判矛盾;措辞不一致 ≠ 矛盾,宁漏报不误报;项目可在 `.claude/memory/synonyms.md` 维护等价组降低误报率
|
||||
4. **污染检测边界**(重申)— 架构层级保留 / 具体类名路径删除
|
||||
5. **被调用静默返回** — `/memory-sync` 内 Phase 9 不输出收尾
|
||||
|
||||
@@ -8,7 +8,8 @@ description: 项目记忆体系完整同步。Git检查→远程补充本地→
|
||||
记忆体系完整同步周期。**本地 `.claude/memory/` 是唯一权威**,远程为镜像。会话目录 = `$PROJECT_DIR`。
|
||||
|
||||
```
|
||||
Phase 0-4 前置(git + 锚点 + 远程→本地补充 + 多机检测 + diff)
|
||||
Phase 0 Git 准备(冲突解决优先 → 普通变更提交)
|
||||
Phase 1-4 前置(锚点 + 远程→本地补充 + 多机/并发检测 + diff)
|
||||
Phase 5 /memory-update(本地写入)
|
||||
Phase 6 /memory-lint(收敛)
|
||||
Phase 7-9 CLAUDE.md 维护与记忆引导区块注入
|
||||
@@ -18,15 +19,48 @@ Phase 11 完成报告
|
||||
|
||||
---
|
||||
|
||||
## Phase 0 — Git 检查
|
||||
## Phase 0 — Git 准备(冲突解决 → 变更提交)
|
||||
|
||||
```bash
|
||||
git -C "$PROJECT_DIR" status --short
|
||||
```
|
||||
|
||||
- 有未提交变更 → 展示文件、询问 commit message(默认 `chore: sync before memory update`)→ `git add .claude/memory/ && git commit -m "<msg>"` → 记新 hash
|
||||
- 干净 → `git rev-parse --short HEAD` → `$HEAD_HASH`
|
||||
- 非 git 仓库 → 跳过 Phase 0,commit 字段填 `N/A`
|
||||
非 git 仓库 → 跳过 Phase 0,commit 字段填 `N/A`。
|
||||
|
||||
### Step 1 — 冲突优先检测(必须先于 commit)
|
||||
|
||||
```bash
|
||||
git -C "$PROJECT_DIR" diff --name-only --diff-filter=U -- .claude/memory/
|
||||
```
|
||||
|
||||
有冲突文件(输出非空)→ 执行**语义合并**(见规则表)→ `git add .claude/memory/ && git commit -m "chore: resolve memory merge conflicts"` → 更新 `$HEAD_HASH` → 跳至 Phase 1。
|
||||
|
||||
无冲突 → 继续 Step 2。
|
||||
|
||||
**语义合并规则**(冲突文件逐个处理):
|
||||
|
||||
| 冲突类型 | 处理方式 |
|
||||
|---------|---------|
|
||||
| frontmatter `last_updated` | 取两者较新日期 |
|
||||
| frontmatter `commit` | 取 HEAD 侧(本地权威) |
|
||||
| `## Section` 块 — 两边内容相同 | 保留一份 |
|
||||
| `## Section` 块 — 仅本地有 | 保留 |
|
||||
| `## Section` 块 — 仅远端有 | 追加到文件末尾 |
|
||||
| `## Section` 块 — 两边均有且不同 | 本地原位保留,远端追加为 `## [合并待审] Section`,标注 `<!-- merge-conflict: YYYY-MM-DD -->` |
|
||||
| `MEMORY.md` 索引 | 取本地版本,不尝试合并;Phase 6 lint 重建 |
|
||||
| `user_profile.md` / `synthesis_*.md` | 整文件不自动合并,在文件头追加 `<!-- merge-conflict: YYYY-MM-DD, NEED-HUMAN -->` |
|
||||
|
||||
合并前备份:
|
||||
```bash
|
||||
cp "$conflicted_file" "${conflicted_file%.md}.conflict_backup_$(git rev-parse --short HEAD).md"
|
||||
```
|
||||
备份文件加入 `.gitignore`(`*.conflict_backup_*.md`),不提交。
|
||||
|
||||
### Step 2 — 普通变更提交
|
||||
|
||||
有未提交变更(非冲突)→ 展示文件、询问 commit message(默认 `chore: sync before memory update`)→ `git add .claude/memory/ && git commit -m "<msg>"` → 记新 hash。
|
||||
|
||||
干净工作区 → `git rev-parse --short HEAD` → `$HEAD_HASH`。
|
||||
|
||||
---
|
||||
|
||||
@@ -81,6 +115,34 @@ done
|
||||
- `n` → 终止整个 sync 流程
|
||||
- `y` → 继续(Phase 10 仍按本地权威覆盖远程)
|
||||
|
||||
### 并发分歧检测(mtime 差 < 7 天的冲突预警)
|
||||
|
||||
对「两边都存在且 mtime 差 < 7 天」的文件,进一步做内容比对:
|
||||
|
||||
```bash
|
||||
for f in ~/.claude/projects/{PROJECT_KEY}/memory/*.md; do
|
||||
local="$PROJECT_DIR/.claude/memory/$(basename "$f")"
|
||||
[ ! -f "$local" ] && continue
|
||||
diff_days_abs=$(...) # 绝对值 < 7
|
||||
if [ "$diff_days_abs" -lt 7 ] && ! diff -q "$f" "$local" > /dev/null 2>&1; then
|
||||
echo "⚡ $(basename "$f") 双边近期均有改动,内容不同"
|
||||
fi
|
||||
done
|
||||
```
|
||||
|
||||
发现 ≥1 个双边分歧文件 → 执行**轻量节段合并**(不等 git 冲突):
|
||||
|
||||
1. 提取远端文件中所有 `## Section` 块
|
||||
2. 检查本地文件是否含同名 `## Section`:
|
||||
- **不含** → 将整个远端 Section 追加到本地文件末尾(自动合并)
|
||||
- **含且内容相同** → 跳过
|
||||
- **含且内容不同** → 在本地文件该 Section 末尾追加注释:
|
||||
`<!-- remote-diverge: YYYY-MM-DD, 请手动核对 -->`,并将远端版本追加为 `## [远端版本] Section`
|
||||
3. 不修改 `MEMORY.md`(由 Phase 6 lint 重建)
|
||||
4. 完成后输出合并摘要,提示用户审查 `<!-- remote-diverge -->` 标记
|
||||
|
||||
**此步骤的保护边界**:仅处理 decisions.md / feedback*.md / project*.md;`user_profile.md` 和 `synthesis_*.md` 不自动合并(内容主观性强,直接标 NEED-HUMAN)。
|
||||
|
||||
---
|
||||
|
||||
## Phase 4 — diff 范围
|
||||
@@ -164,6 +226,9 @@ cp -pf "$PROJECT_DIR/.claude/memory/"*.md ~/.claude/projects/{PROJECT_KEY}/memor
|
||||
```
|
||||
✓ memory-sync 完成
|
||||
|
||||
⚡ 并发冲突处理:git冲突 N 个文件 / 双边分歧 M 个文件(均为 0 则省略本行)
|
||||
含 <!-- merge-conflict --> / <!-- remote-diverge --> 标记的条目请通过 /memory-lint 审查
|
||||
|
||||
📋 CLAUDE.md [已更新 / 已新建 / 无变更]
|
||||
📖 记忆引导区块 [已注入 / 已刷新 / 无变更]
|
||||
|
||||
@@ -185,8 +250,9 @@ cp -pf "$PROJECT_DIR/.claude/memory/"*.md ~/.claude/projects/{PROJECT_KEY}/memor
|
||||
|
||||
## 执行约束
|
||||
|
||||
1. **Phase 0 最先** — 有未提交代码不允许跳过
|
||||
1. **Phase 0 最先** — 冲突检测(Step 1)必须先于普通变更提交(Step 2);有未解决冲突不允许跳过语义合并直接进入 Phase 1
|
||||
2. **方向严格区分** — Phase 3 只补充 / Phase 10 才覆盖
|
||||
3. **顺序固定** — Phase 5(update)→ Phase 6(lint);lint 在 update 写入完毕后检查
|
||||
4. **统一推送** — update + lint 修改全部本地完成后由 Phase 10 一次推
|
||||
5. **记忆引导区块强制存在** — 每次 sync 后 CLAUDE.md 必须含最新区块,文件清单与 MEMORY.md 严格一致
|
||||
6. **并发冲突处理顺序** — git 冲突(Phase 0 Step 1)→ mtime 分歧合并(Phase 3)→ 两者均完成后才进 Phase 5;`<!-- merge-conflict -->` / `<!-- remote-diverge -->` 标记由 lint 扫描、用户事后审查
|
||||
|
||||
@@ -109,7 +109,7 @@ commit: HASH
|
||||
2. 主题相关 → 新条目末尾追加 `[[file.md#标题]]`
|
||||
3. **反向也补**:被引用的旧条目末尾补充对新条目的引用
|
||||
|
||||
### synthesis 双触发模式
|
||||
### synthesis 触发模式(三路)
|
||||
|
||||
**A. 会话内主动**:会话出现技术选型对比 / Bug 根因 / 架构演进 / 性能安全分析时,主动提议归档为 `synthesis_{type}_{topic}.md`。
|
||||
|
||||
@@ -126,6 +126,37 @@ commit: HASH
|
||||
5. `n` → 原条目末尾加 `<!-- synthesis-decline: YYYY-MM-DD -->`,30 天免打扰
|
||||
6. `skip-all` → 本次不再提议
|
||||
|
||||
### 3C — 即时引用计数快扫(不依赖 lint)
|
||||
|
||||
每次执行 Phase 3 末尾**强制运行**。目的:在短会话或任务型对话中,不依赖 lint 的延迟触发,直接检测 synthesis 升级候选。
|
||||
|
||||
```bash
|
||||
# 对 decisions.md / feedback*.md 的每个 ## 条目,统计被多少不同源文件引用
|
||||
for entry_file in "$PROJECT_DIR/.claude/memory/decisions.md" \
|
||||
"$PROJECT_DIR/.claude/memory/feedback"*.md; do
|
||||
[ -f "$entry_file" ] || continue
|
||||
fn=$(basename "$entry_file")
|
||||
while IFS= read -r title; do
|
||||
count=$(grep -rl "\[\[${fn}#${title}\]\]" \
|
||||
"$PROJECT_DIR/.claude/memory/" --include="*.md" \
|
||||
| grep -v "^${entry_file}$" | wc -l)
|
||||
[ "$count" -ge 3 ] && echo "$count|$fn#$title"
|
||||
done < <(grep "^## " "$entry_file" | sed 's/^## //')
|
||||
done | sort -t'|' -k1 -rn
|
||||
```
|
||||
|
||||
对每条输出候选(`count|file#title`):
|
||||
1. 读原条目内是否含 `**Synthesized:**` → 已升级,跳过
|
||||
2. 读原条目内是否含 `<!-- synthesis-decline: YYYY-MM-DD -->` → 30 天内,跳过
|
||||
3. 以上均无 → 触发提议(同 B 模式 step 3-6)
|
||||
|
||||
**与 lint 的分工**:
|
||||
- Phase 3C(快扫):每次 memory-update 必跑,判据为「存在引用行数」,适合即时触发
|
||||
- lint Phase 3A(精扫):按源文件去重的精确计数,月度健康检查时运行
|
||||
- 两者以 `**Synthesized:**` 标记为唯一判重依据,不重复创建文件
|
||||
|
||||
---
|
||||
|
||||
### 写入要点
|
||||
|
||||
- 仅更新有变化维度,不重写无关文件
|
||||
@@ -161,5 +192,5 @@ commit: HASH
|
||||
2. **不记录可推断内容** — 实现细节、文件路径、git 历史不入库
|
||||
3. **feedback 拆分** — 同主题 >5 条规则 → 拆出 `feedback_{topic}.md`
|
||||
4. **See Also 双向同步** — 新增时扫关联并双向补
|
||||
5. **synthesis 双触发** — 会话主动 + lint Top 反向;`**Synthesized:**` 标记不可覆盖;`<!-- synthesis-decline -->` 标记 30 天免打扰
|
||||
5. **synthesis 三触发** — 会话主动 + Phase 3C 即时快扫 + lint Top 反向;`**Synthesized:**` 标记不可覆盖;`<!-- synthesis-decline -->` 标记 30 天免打扰
|
||||
6. **被调用静默返回** — `/memory-sync` 内执行不输出收尾
|
||||
|
||||
Reference in New Issue
Block a user