executing-plans
executing-plans
Use when executing an implementation plan in the current session as the implementer yourself — your human partner chose inline execution, or no subagent tool is available
stash回顾当前对话,把值得跨会话持久化的信息(用户偏好/反馈、项目决策与约束、踩过的坑、外部资源指针)存进本项目 memory 目录、更新 MEMORY.md 索引,并按需更新 CLAUDE.md。用户说「stash / 保存记忆 / 记一下 / 沉淀一下 / 记住这个」时触发。显式触发,不在会话结束时自动运行。
Independent GitHub snapshot · Automated classification · Original documentation governs
回顾本次对话,把跨会话有用的信息落进 memory,让未来的会话能召回。
记忆写法规范以同目录
MEMORY_SPEC.md为唯一真相源,本文件只定流程,不复述 schema 细节(复述会随规范演化而漂移,这正是 stash 从 command 升级为 skill 的初衷)。执行前先读MEMORY_SPEC.md。
显式触发:/stash、「stash / 保存记忆 / 记一下 / 沉淀一下 / 记住这个」。不自动触发,持久化是写文件的副作用动作,只在用户明确要求时跑。
# 锚到项目根(git toplevel),不用裸 pwd:从子目录触发时 pwd 会偏移、写进错 keyspace 致召回静默丢失
ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd)
MEM="$HOME/.claude/projects/-$(printf '%s' "$ROOT" | sed 's:^/::; s:[^a-zA-Z0-9]:-:g')/memory"
[ -d "$MEM" ] || mkdir -p "$MEM" # 新项目首次 stash 自动建
# MEMORY.md 不存在则建四段骨架(recall 总目录;按 type 分段)
[ -f "$MEM/MEMORY.md" ] || printf '# Memory\n\n## User\n\n## Feedback\n\n## Project\n\n## Reference\n' > "$MEM/MEMORY.md"
echo "$MEM"
路径由项目根(git toplevel,回退 pwd)动态推导,绝不硬编码(通用工具跨项目零修改;硬编码曾把记忆写错机器,裸 pwd 则在子目录触发时写偏)。若 harness 直接给了 memory 目录绝对路径,优先用它。MEM 是 shell 变量、不跨 Bash 调用持久,下面每个用到它的 bash 块都重新派生一次(别依赖上一块的 MEM 还在)。
读 MEMORY_SPEC.md 拿规范,再扫本次对话,列出值得持久化的候选:新知识、做出的决策、发现的坑、配置/基础设施变更、用户反馈与偏好。按 MEMORY_SPEC 判断标准先粗筛(只留跨会话有用的)。
加法 + 减法双扫:除了「值得记什么」(加法),同时扫「本次对话作废了什么」(减法):删除 / 退役 / 下线 / 停用 / 离职 / 决策反转这类破坏性事件,拿去撞现有 memory 的主题:对每个被作废实体名跑全文撞库 LC_ALL=C grep -ril -- '<实体名>' "$MEM"($MEM 重派生见 Step 1;撞全文、不止 name / description,旧值常只散落在他题 memory 的正文里)。命中的进 Step 3 走 supersession / 墓碑,别当没发生。减法事件天生不触发「记一下」,是过时记忆的高发源。
ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd); MEM="$HOME/.claude/projects/-$(printf '%s' "$ROOT" | sed 's:^/::; s:[^a-zA-Z0-9]:-:g')/memory" # 每块各自重派生(变量不跨调用)
awk 'FNR==1{c=0} /^---[[:space:]]*$/{c++; next} c==1 && /^(name|description):/' "$MEM"/*.md 2>/dev/null # 只取 frontmatter 区,防正文顶格示例行混入
对每个候选,比对现有 memory 的 name + description,判断三种关系(不只是去重):
MEMORY_SPEC 的「记状态:时效与变更」节的「变更 ≠ 纠错」+「墓碑」写;绝不新建平行条(并存两条矛盾记忆正是「并存冲突」的根)。候选与旧值冲突、拿不准怎么并的,按下判,且无人值守下任何分支都不许停下来问用户:
套 MEMORY_SPEC 的「记什么 / 不记什么」:不记能从 git log / 代码 / CLAUDE.md 直接获取的,不记只对本次会话有用的临时上下文。留下的若含「坑」,按 MEMORY_SPEC 的「记坑:诚实捕获」记(根因没复现就标「疑似 / 未验证」、不冒充确定、带条件戳)。留下的若含「状态」(角色 / 归属 / 现状 / 实体存废),按 MEMORY_SPEC 的「记状态:时效与变更」记(带 as-of、变更走 supersession、删除立墓碑)。
留下的候选为空就直接到 Step 7 报告「本次无需持久化(理由)」收尾,不为凑产物硬造低价值记忆。
按 MEMORY_SPEC.md 的 frontmatter schema + 正文规范写 / 改(文件名、name 前缀、description、type 枚举、Why/How、坑的诚实捕获等细节都在那,本步不复述、防漂移)。本步只强调流程动作:
MEMORY.md 加 / 改一行索引(按 type 分段),索引与文件一一对应。MEMORY_SPEC「记状态:时效与变更」§2,本机真实时区);混含条的状态部分进 description 也带戳。MEMORY_SPEC「记状态:时效与变更」§3 表 / §4 为准,本步只记方向、不复述格式):
ROOT=$(git rev-parse --show-toplevel 2>/dev/null || pwd); MEM="$HOME/.claude/projects/-$(printf '%s' "$ROOT" | sed 's:^/::; s:[^a-zA-Z0-9]:-:g')/memory" # 每块各自重派生
bash ~/.claude/skills/stash/check.sh "$MEM"
🔴 must-fix 必须修到过;🟡 advisory 逐条 review(多数应修,少数可接受,如指向其它项目 keyspace memory 的带前缀链接:本 keyspace 查不到、属跨库引用)。
CLAUDE.md(无变更跳过)。MEMORY_SPEC.md 为唯一真相源,不在本文件或对话里复述 schema 细节(防漂移)。check.sh,🔴 必修。但 check.sh 只验 schema 合规、不验内容正确:过线 ≠ 记对了,正确性靠诚实捕获 + 下游验证。MEMORY_SPEC),不记 git / code / CLAUDE.md 可直接获取的。MEMORY_SPEC 的「记状态:时效与变更」节)。