项目文件夹

文件
wehub-resource-sync 1d6fd29cda
tests / test (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:36:27 +08:00

373 行
12 KiB
Markdown

此文件含有模棱两可的 Unicode 字符
此文件含有可能会与其他字符混淆的 Unicode 字符。 如果您是想特意这样的,可以安全地忽略该警告。 使用 Escape 按钮显示他们。
# Mem-Sys 实现规划书
> 分支:`Mem-Sys` | 创建于 2026-04-12
## 一、现状分析
现有文件结构:
```
crushes/{slug}/
├── profile.md ← 纯 Markdown 散文,无结构化字段,Claude 读写靠理解
├── strategy.md ← 同上
├── meta.json ← 有结构,但字段稀疏(仅 stage、score、mode
├── memories/chats/ ← 原始聊天记录
└── versions/ ← 手动备份,不自动维护
```
**核心问题**
1. `profile.md` 没有 YAML frontmatter,Claude 无法可靠提取/更新单个字段
2. 没有"当前状态快照",每次 `/simp progress` 都要重新推断阶段
3. 没有事件日志,历史演变不可追溯,`/simp quit` 无法看"感情轨迹"
4. `versions/` 是手动备份,不是真正的历史记录
---
## 二、新文件结构
```
crushes/{slug}/
├── profile.md # 【升级】稳定层 — YAML frontmatter + 叙述体
├── state.md # 【新增】动态层 — 当前快照,每次会话后覆盖
├── events.jsonl # 【新增】事件流 — 只追加,永不删除
├── strategy.md # 【保留】追求策略(不动)
├── meta.json # 【扩展】元数据,新增索引字段
├── memories/
│ ├── chats/
│ ├── social/
│ └── photos/
└── snapshots/ # 【新增】定期快照目录
└── YYYY-MM-DD.json
```
**读取优先级**context window 分配):
| 文件 | 加载时机 | 预估 tokens |
|------|----------|------------|
| `profile.md` | 每次必读 | ~300 |
| `state.md` | 每次必读 | ~200 |
| `events.jsonl` 最近5条 | progress/analyze/quit | ~150 |
| `strategy.md` | message/confess/analyze | ~400 |
| `events.jsonl` 全部 | 用户明确要求回顾时 | 按需 |
---
## 三、文件 Schema 定义
### 3.1 `profile.md`(稳定层)
```markdown
---
nickname: 小雨
slug: xiaoyu
gender: 女
age: 23
occupation: 设计师
city: 上海
mbti: ENFP
zodiac: 双鱼
personality_type: 感性型
how_met: 同学介绍
created_at: "2026-04-10"
---
## 性格画像
ta 话很多,喜欢用颜文字,情绪外露,容易被细节打动。
见面时会不自觉靠近,但如果感觉被冷落会直接不回消息。
## 最打动ta的方式
具体的画面感 > 泛泛的夸奖。说"你刚才皱眉的样子"比"你很可爱"更有效。
## 用户自身风格
说话偏幽默,短句为主,偶尔用表情包,追求混合模式。
## 注意事项
ta 对"套路感"敏感,一旦感觉被设计会直接拉远距离。
```
**规则**
- YAML frontmatter 存结构化字段,Claude 更新时用字段名精确修改
- 正文存叙述性内容,只追加,不覆盖
- `personality_type` 枚举值:`感性型 | 理性型 | 傲娇型 | 温柔型`
---
### 3.2 `state.md`(动态层)
```markdown
---
current_stage: 暧昧期
signal_score: 17
last_signal_score: 14
score_trend: up
recommended_mode: 混合
last_updated: "2026-04-12T10:30:00"
milestones_done: 7
---
## 当前状态(一句话)
关系持续升温,ta 开始主动制造见面机会。
## 最近信号(最新3条)
- 🟢 2026-04-11 ta 主动问周末有没有空
- 🟢 2026-04-10 深夜发了消息说"突然想到你"
- 🟡 2026-04-08 回复比往常慢了一些
## 当前策略方向
暧昧期推进:制造1v1心跳时刻,评估表白时机是否成熟。
## 下一步建议
本周制造一次晚间1v1见面,用 /simp message 准备好开场话题。
```
**规则**
- 每次 `/simp analyze``/simp progress` 结束后**全量覆盖**
- `score_trend` 枚举:`up | down | stable`
- `current_stage` 枚举:`破冰期 | 升温期 | 暧昧期 | 表白前 | 表白后-成功 | 表白后-被拒 | 友谊区 | 重启期`
---
### 3.3 `events.jsonl`(事件流)
每行一个独立 JSON 对象,严格只追加:
```jsonl
{"ts":"2026-04-10T14:00:00","v":1,"type":"profile_created","slug":"xiaoyu","data":{"nickname":"小雨","personality_type":"感性型"}}
{"ts":"2026-04-11T20:30:00","v":1,"type":"signal_recorded","slug":"xiaoyu","data":{"direction":"green","content":"深夜主动发消息说突然想到你","score_delta":3}}
{"ts":"2026-04-12T10:30:00","v":1,"type":"stage_changed","slug":"xiaoyu","data":{"from":"升温期","to":"暧昧期","trigger":"连续3天主动联系 + 深夜消息"}}
{"ts":"2026-04-12T10:30:00","v":1,"type":"analysis_done","slug":"xiaoyu","data":{"score":17,"stage":"暧昧期","summary":"ta 主动性明显增强,信号偏绿"}}
```
**事件类型字典**
| type | 触发指令 | data 必填字段 |
|------|---------|--------------|
| `profile_created` | `/simp create` | nickname, personality_type |
| `profile_updated` | `/simp update` | field, old_value, new_value |
| `stage_changed` | analyze/progress | from, to, trigger |
| `signal_recorded` | `/simp analyze` | direction(green/red/neutral), content, score_delta |
| `analysis_done` | `/simp analyze` | score, stage, summary |
| `progress_evaluated` | `/simp progress` | score, stage, milestones_done, next_actions |
| `strategy_updated` | 阶段变化时 | old_stage, new_stage, reason |
| `crisis_handled` | `/simp crisis` | crisis_type, resolution |
| `quit_evaluated` | `/simp quit` | verdict(continue/reconsider/let_go), reason |
| `confess_prepared` | `/simp confess` | method, readiness_score |
---
### 3.4 `meta.json`(扩展)
```json
{
"slug": "xiaoyu",
"nickname": "小雨",
"created_at": "2026-04-10T14:00:00",
"updated_at": "2026-04-12T10:30:00",
"version": "v1",
"current_stage": "暧昧期",
"signal_score": 17,
"mode": "hybrid",
"event_count": 4,
"last_snapshot": "2026-04-12"
}
```
新增字段:`nickname`(用于 list 展示)、`event_count`(快速统计)、`last_snapshot`
---
## 四、每条指令的 Memory Protocol
```
指令 读取 写入
─────────────────────────────────────────────────────────
/simp create 无 profile.md(新建)
state.md(空模板)
events.jsonl(新建)
meta.json(新建)
/simp analyze profile.md state.md(覆盖)
state.md events.jsonl(追加:
signal_recorded
analysis_done
stage_changed 若变化)
/simp message profile.md 无
state.md
strategy.md
/simp progress profile.md state.md(覆盖)
state.md events.jsonl(追加:
events.jsonl 最近5条 progress_evaluated)
meta.json(更新score/stage)
/simp update profile.md profile.md(更新frontmatter)
events.jsonl(追加:
profile_updated)
/simp confess profile.md events.jsonl(追加:
state.md confess_prepared)
strategy.md
/simp crisis profile.md state.md(更新状态)
state.md events.jsonl(追加:
crisis_handled)
/simp daily state.md 仅此 无
/simp quit profile.md events.jsonl(追加:
state.md quit_evaluated)
events.jsonl 全部
/simp list meta.json(所有slug) 无
```
---
## 五、新增 Python 工具:`tools/memory.py`
### 5.1 模块职责
`memory.py` 是记忆系统的唯一入口,`skill_writer.py` 调用它,Claude 通过 shell 调用它。
### 5.2 CLI 接口
```bash
# 追加事件
python3 tools/memory.py append <slug> <event_type> '<json_data>'
# 读取最近N条事件
python3 tools/memory.py events <slug> --last 5
# 读取当前上下文(profile.md + state.md 合并输出)
python3 tools/memory.py context <slug>
# 从事件流重建 state.md
python3 tools/memory.py rebuild <slug>
# 生成日快照
python3 tools/memory.py snapshot <slug>
# 查看事件时间线
python3 tools/memory.py timeline <slug>
```
### 5.3 核心函数签名
```python
def append_event(
slug: str,
event_type: str,
data: dict,
base_dir: Path = DEFAULT_BASE_DIR
) -> None:
"""追加一条事件到 events.jsonl,同时更新 meta.json 的 event_count"""
def get_recent_events(
slug: str,
n: int = 5,
event_types: list[str] | None = None,
base_dir: Path = DEFAULT_BASE_DIR
) -> list[dict]:
"""返回最近 N 条事件,可按 type 过滤"""
def load_context(
slug: str,
include_strategy: bool = False,
base_dir: Path = DEFAULT_BASE_DIR
) -> str:
"""拼装 profile.md + state.md,供 Claude 直接注入 context"""
def update_state(
slug: str,
frontmatter_updates: dict,
sections: dict[str, str],
base_dir: Path = DEFAULT_BASE_DIR
) -> None:
"""全量覆盖 state.md,frontmatter_updates 更新 YAML 字段"""
def take_snapshot(
slug: str,
base_dir: Path = DEFAULT_BASE_DIR
) -> Path:
"""将 meta.json + state.md frontmatter 合并写入 snapshots/YYYY-MM-DD.json"""
def rebuild_state_from_events(
slug: str,
base_dir: Path = DEFAULT_BASE_DIR
) -> dict:
"""从 events.jsonl 重放,返回推断的当前状态(用于校验或恢复)"""
```
---
## 六、`skill_writer.py` 改动
`init_crush()` 新增三步:
1.`profile.md` 模板顶部加 YAML frontmatter
2. 创建 `state.md`(空模板)
3. 创建 `events.jsonl`(空文件)
4. 创建 `snapshots/` 目录
5. `meta.json` 新增 `nickname``event_count: 0``last_snapshot: null` 字段
`backup_crush()` 扩展:同步备份 `state.md`events.jsonl 不备份,它是不可变历史)。
`update_meta()` 扩展:支持更新 `nickname``event_count``last_snapshot`
---
## 七、`SKILL.md` 改动(Phase 3
在「运行规则」之前新增「记忆操作协议」章节,定义每条指令的读写规则。
---
## 八、实施步骤
### Phase 1Schema 落地(基础)✅
- [x] 更新 `init_crush()` — 新增 `state.md``events.jsonl``snapshots/` 的创建
- [x] 更新 `profile.md` 模板 — 加 YAML frontmatter
- [x] 扩展 `meta.json` schema — 新增字段
- [x] 更新测试
### Phase 2memory.py 工具 ✅
- [x] 实现 `append_event()`
- [x] 实现 `get_recent_events()`
- [x] 实现 `update_state()`
- [x] 实现 `load_context()`
- [x] 实现 `take_snapshot()`
- [x] 实现 `rebuild_state_from_events()`
- [x] CLI 入口
- [x] 测试覆盖(见 `tests/test_memory.py`
### Phase 3SKILL.md 集成 ✅
- [x] 新增「记忆操作协议」章节
- [x] 每条指令补充 Memory Protocol 说明
- [x] `progress_tracker.md` 更新读取路径
### Phase 4:迁移工具 · ❌ 不再计划
早期阶段无存量用户档案,迁移工具的实际价值低于维护成本。新档案统一通过 `init_crush()` 创建,已自带 YAML frontmatter / `state.md` / `events.jsonl`,无需迁移。若未来出现存量数据需要升级,再单独立项。
---
## 九、测试计划
```
tests/
├── test_skill_writer.py # 已有,补充新字段断言 ✅
└── test_memory.py # 新增(Phase 2)✅
```
---
## 十、一句话原则备忘
| 文件 | 一句话规则 |
|------|-----------|
| `profile.md` | 只增不减,YAML 字段可更新,正文只追加 |
| `state.md` | 代表"现在",每次全量覆盖 |
| `events.jsonl` | 代表"历史",只追加,永不删除 |
| `strategy.md` | 阶段变化时更新,其他时候只读 |
| `snapshots/` | 每日自动生成,用于跨会话快速恢复 |