新增三条架构决策:
- synonyms.md 作为独立等价词表文件(type: reference)
- synthesis 三触发分工:快扫 vs 精扫的职责边界
- memory-sync Phase 0 冲突检测必须先于 git commit
更新 project_overview.md:memcore 插件描述补充新能力说明
刷新 MEMORY.md 索引锚点至 f26e741
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
6.3 KiB
name, description, type, last_updated, commit
| name | description | type | last_updated | commit |
|---|---|---|---|---|
| 架构决策 | Marketplace 设计中的关键技术决策及其原因 | project | 2026-05-10 | f26e741 |
关键架构决策
plugin.json 不设 version 字段
结论:所有 plugin.json 均不含 version 字段。
Why:Claude Code 官方文档说明,若 plugin.json 设置了固定 version,推送新 commit 不改 version 字符串时,已安装用户看不到更新。省略 version 后,Claude Code 自动用 git commit SHA 做版本判断,每次推送 main 分支即为新版本。
How to apply:新增插件时不要加 version 字段。memcore 和 huanxi 均已按此规范执行。
huanxi plugin 使用 userConfig 而非环境变量传 Token
结论:plugin.json 用 userConfig + sensitive: true 声明 Bearer Token 输入,mcpServers.headers 中用 ${user_config.token} 引用。
Why:sensitive: true 将 token 存入系统钥匙链(或 ~/.claude/.credentials.json),不会出现在 settings.json 中,避免随仓库提交泄露。Claude Code 安装插件时自动弹窗提示用户输入,体验好于环境变量。
How to apply:其他需要用户配置 API Key/Token 的插件,均应使用此模式,不要用 ${ENV_VAR} 方式。
"userConfig": {
"token": {
"type": "string",
"title": "寰汐 Personal Token",
"description": "在寰汐系统后台生成,hxp_ 前缀",
"sensitive": true
}
}
See Also:project_overview.md#已发布插件
huanxi MCP Server 认证:Bearer Token 直连,不改后端
结论:plugin.json 配置 Authorization: Bearer ${user_config.token} header,MCP server 已有的 _PersonalTokenVerifier 直接验证 hxp_ token,无需改后端。
Why:后端已有 ASGI 中间件模式(AdminMcpAuthMiddleware)和 PersonalTokenVerifier,Bearer Token 天然支持。OAuth2 Discovery Flow 是 FastMCP 框架层的特性,当客户端直接在 header 中传 Bearer Token 时可绕过 OAuth 流程。改后端风险高且无必要。
How to apply:未来新增 MCP server 插件时,只需在 plugin.json 配置 header,不需要修改后端认证逻辑。
memcore memory-update/lint 路径锁定:禁止写入系统自动记忆路径
结论:memory-update 和 memory-lint 的唯一操作路径锁定为 $PROJECT_DIR/.claude/memory/;严禁写入 ~/.claude/projects/*/memory/;两个技能执行期间不触发 auto memory 系统写入。
Why:Claude Code 的 auto memory 是 system-level 指令,在技能执行期间始终有效。若技能只在 description 中说"不推送远程"而无显式路径约束,AI 会在执行 memory-update/lint 时被 auto memory 指令并发触发,将内容写入系统级路径(~/.claude/projects/xxx/memory/),背离"项目本地 .claude/memory/ 是唯一权威"的初衷。
How to apply:两个技能均在正文最前加"⚠ 路径锁定"块(含禁止路径清单 + 执行前断言代码),memory-sync 的 Phase 3 加方向锁定注释(Phase 10 是唯一远程写入窗口)。未来新增操作本地记忆的技能也应遵循同等约束。
See Also:project_overview.md#已发布插件
memcore:synonyms.md 作为独立等价词表文件
结论:等价表述清单以独立的 synonyms.md(type: reference)存放于 .claude/memory/,而非内嵌到 feedback.md。
Why:feedback.md 存放协作规范(含 Why + How to apply),语义上属于"决策";synonyms.md 是纯配置数据,在 lint Phase 4 矛盾检测前作为输入加载。两者职责不同,混放会让 lint 的加载逻辑复杂化。type: reference 符合"外部参考资料"语义,且该类型已在 frontmatter 枚举中。
How to apply:新建项目记忆体系时,若项目有领域专有术语缩写(如 PG/PostgreSQL、KT/Kotlin),在 .claude/memory/synonyms.md 中维护等价组(每行逗号分隔)。幽灵检测自动排除该文件,不纳入 MEMORY.md 索引。
See Also:decisions.md#memcore memory-update/lint 路径锁定:禁止写入系统自动记忆路径
memcore:synthesis 三触发分工——快扫 vs 精扫
结论:synthesis 升级触发拆为三路:A 会话内主动、B Phase 3C 即时快扫(每次 memory-update 必跑)、C lint Top 反向触发(月度运行)。
Why:原双触发中,B 路径依赖 lint 生成 lint_report.md 的「条目级高频引用 Top」段,短会话或任务型对话中 lint 常被跳过,导致高频引用条目长期未升级为 synthesis。Phase 3C 快扫在每次 memory-update 结束时强制执行,覆盖短会话盲区;lint 精扫按源文件去重计数,用于月度深度检查。两者以 **Synthesized:** 标记作为唯一判重依据,不重复创建文件。
How to apply:实现新的 memory-update 类技能时,引用计数类检查应分"即时快扫"和"月度精扫"两档,分别对应"覆盖率"和"准确率"的不同优先级。
memcore memory-sync:冲突检测必须先于 git commit
结论:memory-sync Phase 0 重构为两步:Step 1 冲突优先检测(diff --diff-filter=U)→ Step 2 普通变更提交。冲突语义合并完成后才允许 commit,再进入 Phase 1。
Why:原设计中 Phase 0 先执行 git add + commit,Phase 0.5 才检测冲突。若文件存在 git merge conflict markers,git commit 会静默失败(git 拒绝提交含冲突标记的文件),整个 sync 流程进入不确定状态且无明显报错。改为"先检测再提交"消除了这条静默失败路径。
How to apply:设计任何含"检测 + 操作"两步的流程时,检测必须先于操作,且检测结果应作为操作的前置条件,而非事后处理。
SKILL.md frontmatter 只保留 name 和 description
结论:SKILL.md frontmatter 只写 name 和 description 两个字段,去掉 version。
Why:Claude Code 插件规范中 SKILL.md frontmatter 只定义了 name 和 description。version 字段不在规范内,silently ignored,且与 plugin.json 层面的版本管理重复。已从所有 huanxi skill 文件中移除。
How to apply:新建 SKILL.md 时只写这两个字段。description 字段写用户实际口语触发词(第三人称描述),不要用"当需要…时触发"的内部视角表达。