一键导入
personal-dev-guard
Use this skill before or during code changes and code review to enforce readable, restrained, maintainable code with low patch smell.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Use this skill before or during code changes and code review to enforce readable, restrained, maintainable code with low patch smell.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
审查、安装、配置、激活、验证、更新和回滚 AgentDock Skill 时使用;负责来源校验、安全评估、环境配置和已安装版本验收。
Manage a Linkwarden instance through its official HTTP API: check configuration, search and inspect bookmarks, collections, tags and highlights, and perform controlled link, collection or tag changes with explicit confirmation for destructive actions.
Search, read, create, update and organize notes in a Trilium Notes instance through the official ETAPI, including revisions, branches, attributes, attachments, calendar notes and explicitly confirmed destructive operations.
Use this skill to query and manage subscriptions in a self-hosted Wallos instance through its official HTTP API. Covers subscriptions, monthly cost, categories, currencies, payment methods, household members, and the current user; excludes administrator, OIDC, notification-secret, Fixer, and generic API management.
OpenList v4 HTTP API integration for AgentDock: authentication, file browsing/search, safe text uploads, file operations, storage/driver inspection, and restricted generic API calls.
创建、设计、修改、升级、重构和验证 AgentDock Skill 时使用;负责可移植核心、文档、引用、辅助脚本、测试、版本和本地安装验证。
| name | personal-dev-guard |
| description | Use this skill before or during code changes and code review to enforce readable, restrained, maintainable code with low patch smell. |
| version | 0.1.6 |
这是一个中文指令型 Skill。它的本体是这份 Markdown 文档,而不是自动评分脚本。
使用者读取本规范后,应按用户的个人高级开发标准进行代码开发和代码审查。这里的重点不是部署、排障、工具调用礼仪,也不是形式化流程检查,而是判断一份代码是否清晰、可读、克制、可维护,是否像高级开发者写出来的代码。
开发和审查代码时,优先遵守以下原则:
any 不算泛型,但也要克制:边界层解析动态 JSON 可以用,业务内部优先转成明确 struct、具体类型或小结构,避免把字段契约藏进运行时。如果因为现实约束违反核心偏好,必须在 Review 或交付说明中说清楚:为什么违反、替代方案是什么、风险是什么、后续是否需要修正。
本规范约束的是代码开发质量,不是 AgentDock 运维流程。
它应该用于:
它不重点覆盖:
这份规范不是要求所有代码都写成一种形状,而是帮助开发者始终回答一个问题:未来接手这段代码的人,能不能顺着读懂、放心修改、快速定位问题?
当“最小改动”和“长期正确”冲突时,不能默认选择最小改动。应该优先选择符合项目规范、能形成完整闭环、未来维护成本更低的方案;如果只能先临时处理,必须说明临时性、风险和后续正式方案。
高级开发者不是把代码写得复杂,而是把真实复杂度控制在可读、可定位、可维护的范围里。
优先级如下:
不高级的代码通常有这些味道:
主流程优先连贯。能在一个函数或一段清楚代码里顺着读懂的业务链路,不要为了形式上的“短函数”拆成一堆独立小方法。
允许拆分,但拆分必须服务于可读性,而不是破坏可读性。合理拆分的理由包括:
不接受的拆分理由包括:
如果确实拆分,入口或主流程仍然应该像目录一样清楚展示完整业务顺序。读者不应该为了理解主线,在多个 helper 里来回跳转。
func UpdateUser(ctx context.Context, req UpdateUserRequest) error {
user, err := loadUser(ctx, req)
if err != nil {
return err
}
prepareUser(user)
applyRequest(user, req)
normalizeUser(user)
fillAuditFields(user)
return saveUser(ctx, user)
}
这段代码的问题不是函数短,而是读者必须跳进多个 helper 才知道用户到底被改了什么。
func UpdateUser(ctx context.Context, req UpdateUserRequest) error {
if req.UserID == "" {
return fmt.Errorf("用户 ID 不能为空")
}
user, err := repo.FindUser(ctx, req.UserID)
if err != nil {
return fmt.Errorf("查询用户失败: %w", err)
}
// 核心字段变更保持在主流程中,方便读者直接看到本次更新会影响什么。
user.Name = strings.TrimSpace(req.Name)
user.Email = strings.ToLower(strings.TrimSpace(req.Email))
user.UpdatedAt = clock.Now()
if err := validateUserForUpdate(user); err != nil {
return err
}
return repo.SaveUser(ctx, user)
}
这里不是禁止 helper,而是把关键业务变化留在主流程里,让读者能顺着读懂。
代码不追求短,也不追求抽象,追求业务复杂度本身可见、可读、可定位。
要求:
判断一段代码是否可读,可以问:
不反对抽象,但抽象必须来自真实需求。
允许抽象的理由:
不接受的理由:
接口、抽象层、目录结构都应该减少理解成本,而不是制造跳转成本。
Go 项目优先简单直接,尊重 Go 的工程习惯,不做 Java 式机械分层。
偏好:
any 不是泛型,但同样不要随手使用;除非处在 MCP/HTTP/JSON/插件 manifest 这类动态边界,业务逻辑内部优先使用明确 struct、具体字段和具体类型。map[string]any 接住外部输入,但进入核心流程前应尽快校验并转成明确 request struct;不要让 any 和字符串 key 在业务链路里到处传。any、万能 DTO 或 map[string]any 伪装通用性;字段契约如果对维护者重要,就应该让类型、命名或局部结构直接表达出来。Go 里的 interface 应该由消费方在真实需要时定义,而不是在实现方提前制造抽象。
命名优先服务阅读,让读者快速理解“这是什么、为什么存在、在业务里代表什么”。
要求:
canSync、shouldRetry、hasPermission。一个名字如果需要读实现才能知道它代表什么,通常就不够好。
注释默认使用中文,方便长期维护和快速理解。
要求:
好的注释应该降低未来阅读成本,不应该替代糟糕命名和糟糕结构。
允许现实中的临时处理,但必须说明清楚,不能伪装成正式设计。
要求:
临时处理如果没有退出条件,就很容易变成永久技术债。
错误路径要和正常路径一样容易读懂。
要求:
失败路径如果读不懂,代码就不可靠。
高级开发不是引入更多依赖和框架,而是知道什么时候不引入。
要求:
并发和缓存不是高级感来源,清楚可靠才是。
该测的一定测;不适合自动化测试的,必须给出替代验证和理由。
优先测试:
测试代码本身也必须可读:
测试不是为了覆盖率数字,而是为了覆盖这次改动真正的风险。
改动必须服务当前目标,不做无关美化和范围膨胀;但“克制”不等于只做最小改动,更不等于留下长期不一致。
要求:
简化比新增抽象更优先,但简化也必须有边界。
如果为长期规范性需要扩大改动范围,应明确说明扩大范围的必要性、涉及面、验证方式和剩余风险,而不是假装这是一个“小修”。
Review 时按以下优先级判断:
Review 必问:
any / map[string]any?这些动态值是否只停留在边界层,进入核心流程前是否转成了明确结构?如果违反核心偏好,Review 必须说明:违反了哪条、为什么必须这样做、风险是什么、后续是否需要修正。
坏例子:
type UserServiceInterface interface {
UpdateUser(ctx context.Context, req UpdateUserRequest) error
}
type UserServiceImpl struct {
repo UserRepositoryInterface
}
如果当前只有一个实现,没有外部边界,也没有真实替身需求,这种 interface 只是增加跳转。
好例子:
type UserService struct {
repo *UserRepository
}
等出现真实边界时,再在消费方定义需要的 interface。
坏例子:
if user.ID == "legacy" {
return nil
}
好例子:
// 兼容 2024 年旧导入任务产生的 legacy 用户记录。
// 这类记录没有完整资料,当前只跳过同步,避免阻断正常用户更新。
// 旧数据迁移完成后可删除该分支,迁移任务见 internal/migrate/legacy_users.go。
if user.ID == "legacy" {
return nil
}
坏例子:
func TestUpdate(t *testing.T) {
mock := newComplexMockFactory().WithA().WithB().Build()
got := run(mock)
assert.Equal(t, true, got)
}
好例子:
func TestUpdateUser_邮箱为空时返回错误(t *testing.T) {
req := UpdateUserRequest{UserID: "u1", Email: ""}
err := service.UpdateUser(context.Background(), req)
if err == nil || !strings.Contains(err.Error(), "邮箱不能为空") {
t.Fatalf("期望返回邮箱为空错误,实际: %v", err)
}
}
测试名称和断言直接表达业务行为,失败时也能定位原因。
当你读取本 Skill 后,应将它作为用户的个人代码开发标准执行。
要求: