Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 13 additions & 2 deletions .github/workflows/validate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,21 @@ jobs:
- name: Install pyyaml
run: pip install pyyaml

- name: Validate SKILL.md frontmatter + required files
run: python3 scripts/validate-skill.py .
- name: Validate SKILL.md + routing + self-check (strict)
run: python3 scripts/validate-skill.py --strict .

- name: Smoke test build
run: |
python3 scripts/build-skill.py /tmp/dist
test -f /tmp/dist/gospec.skill

- name: Smoke test install.sh in clean dir
run: |
mkdir -p /tmp/install-test
cd /tmp/install-test
SKILL_DIR=$GITHUB_WORKSPACE bash $GITHUB_WORKSPACE/scripts/install.sh
test -f AGENTS.md
test -f .cursor/rules/gospec.mdc
# 校验 cursor 规则的 frontmatter(globs / alwaysApply)
head -5 .cursor/rules/gospec.mdc | grep -q "^globs:"
head -5 .cursor/rules/gospec.mdc | grep -q "^alwaysApply:"
21 changes: 21 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,27 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- **SKILL.md `description` 大幅缩短**(~1024 字符 → ~250 字符),提升 agent 激活匹配准确率。
- **软化 3 条过严的"强制约束"**,与 Go 生态实际一致:
- `init()` 改为"仅允许做注册(pprof / collector / driver),禁止 IO 或可能 panic"
- `interface{}` 改为"避免出现在公共 API 边界,解码 / SDK 适配等不可避免场景就近注释"
- `utils/` 改为"仅作最后兜底,优先按职责拆 `mathx/` / `strx/`"
- 三处同步更新:`spec/spec.md` / `spec/05-coding/README.md` / `docs/templates/project-agents-template.md`。
- **CI 切到 `--strict` 模式**,路由表完整性 + 自查清单缺失视为失败,防 spec 漂移。

### Added (Cursor 体验)

- **`docs/templates/cursor-rule-template.mdc`**:Cursor 单文件规则模板,自带 `globs: [**/*.go, **/*.proto, ...]` + `alwaysApply: false`,让 Cursor 在编辑相关文件时自动附加,**避免每次让用户手动选择规则**。
- **`scripts/install.sh` 同时落 `.cursor/rules/gospec.mdc`**,可通过 `NO_CURSOR=1` 跳过;本地落后远端时自动提示更新命令。

### Added (校验强化)

- **路由表完整性校验**:`scripts/validate-skill.py` 检查 `spec/spec.md` 路由表里引用的所有 spec 子文件是否真实存在,防 broken link。
- **自查清单存在校验**:每个 spec 子文件须有 `## 自查` / `## Checklist` 标题小节,否则在 `--strict` 模式下报错。已为缺失的两个文件补上(`spec/09-documentation.md`、`spec/01-requirement/lifecycle.md`);`spec/07-code-review.md` 整体即为 PR 自查清单,列入例外。
- **install.sh 端到端冒烟测试**:CI 模拟在干净目录运行 install.sh,校验 `AGENTS.md` 和 `.cursor/rules/gospec.mdc` 落盘 + frontmatter 正确。

### Added

- **SDLC spec 骨架**(`spec/`):覆盖从需求到运维的 13 个阶段,每阶段按主题拆分为子文件,通过 `spec/spec.md` 的任务路由表按需加载。
Expand Down
13 changes: 8 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -169,21 +169,24 @@ npx skills add singchia/gospec -g # 安装到 ~/.claude/skills/gospec/

之后 Claude Code 等支持 SKILL.md 的 agent 会在你写 / 审查 / 重构 Go 代码时自动激活 gospec,并在首次激活时主动询问是否在项目根创建 `AGENTS.md`。

### 方式二:`install.sh`(一行命令,自动落 AGENTS.md)
### 方式二:`install.sh`(一行命令,自动落 AGENTS.md + Cursor 规则

如果你想立刻把 `AGENTS.md` 落到项目根(不等 agent 提示),或者你的 agent 不读 SKILL.md 必须靠 AGENTS.md 触发:
如果你想立刻把规则落到项目根(不等 agent 提示),或者你的 agent 不读 SKILL.md 必须靠 AGENTS.md / Cursor rules 触发:

```bash
cd your-go-project
bash <(curl -sSL https://raw.githubusercontent.com/singchia/gospec/main/scripts/install.sh)
```

这一行会做两件事
这一行会做三件事

1. **安装 gospec skill** 到 `~/.claude/skills/gospec/`(如果还没装)
2. **在当前目录创建 `AGENTS.md`**,让任何 AI agent 打开本项目就知道遵循 gospec
2. **在项目根创建 `AGENTS.md`**(Codex / Cline / 通用 agent 入口)
3. **在项目根创建 `.cursor/rules/gospec.mdc`**(Cursor 单文件规则,自带 `globs`,编辑 `.go` / `.proto` / `Dockerfile` / migration 时自动附加,**避免 Cursor 每次让用户手动选择**)

之后任何 agent(Claude Code、Cursor、Cline、Codex、Gemini CLI、GitHub Copilot)打开你的项目,第一眼看到 `AGENTS.md` 就被引导到 gospec 的任务路由表 + 核心约束。
跳过 Cursor 落盘:`NO_CURSOR=1 bash <(curl ...)`

之后任何 agent(Claude Code / Cursor / Cline / Codex / Gemini CLI / GitHub Copilot)打开你的项目,都会自动加载 gospec 的任务路由表 + 核心约束。

> **AGENTS.md vs SKILL.md 的区别**:
> - `SKILL.md` 是 Claude Code 通过 [skills.sh](https://skills.sh) 协议自动加载的入口,作用域是整个 skill
Expand Down
2 changes: 1 addition & 1 deletion SKILL.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
---
name: gospec
description: "Go backend SDLC spec skill (Chinese content). Covers 13 stages: requirements (Issue/RFC/PRD/Epic), architecture (layering + monorepo), API (proto/gRPC/HTTP), data models (MySQL/Redis/ClickHouse/InfluxDB), coding (10 design patterns), testing, code review, CI/CD, docs, observability (SLO/metrics/traces), security (authN/Z/threat-modeling/supply-chain), operations (incidents/runbooks/postmortems), and database migration. Use when writing or reviewing Go code, designing APIs or data schemas, writing tests, configuring CI/CD, setting up SLO and monitoring, handling security/secrets/compliance, writing deployment or incident plans, writing DB migrations, or drafting PRD/RFC/ADR/HLD docs. Go 后端项目 SDLC 全流程中文规范。覆盖需求/架构/API/数据模型(MySQL Redis ClickHouse InfluxDB)/编码/测试/代码审查/交付/文档/可观测性/安全/运维/数据库迁移 13 阶段。当编写或审查 Go 代码、设计 API 或数据模型、写测试、配 CI/CD、处理监控告警 SLO、安全 密钥 合规、写部署或事故响应方案、写数据库 migration、撰写 PRD RFC ADR HLD 文档时使用。"
description: "Go 后端 SDLC 全流程中文规范(Kratos / gRPC / GORM / MySQL / Redis / ClickHouse / InfluxDB)。写或审查 Go 代码、设计 API / 数据模型 / 架构、写测试、配 CI/CD、做日志指标追踪 SLO、处理认证密钥安全、写部署或事故方案、写数据库 migration、起草 PRD / RFC / ADR / HLD 时按需加载。Go backend SDLC spec skill — load on demand for coding, API/schema design, testing, CI/CD, observability, security, ops, DB migration, and PRD/RFC/ADR/HLD docs."
license: MIT
---

Expand Down
89 changes: 89 additions & 0 deletions docs/templates/cursor-rule-template.mdc
Original file line number Diff line number Diff line change
@@ -0,0 +1,89 @@
---
description: gospec — Go 后端 SDLC 规范,编写/审查 Go / proto / migration / Dockerfile 时自动加载
globs: ["**/*.go", "**/*.proto", "go.mod", "go.sum", "**/Dockerfile", "**/*.sql", "docs/rfc/**/*.md", "docs/adr/**/*.md", "docs/requirements/**/*.md"]
alwaysApply: false
---

# gospec —— Go 后端 SDLC 规范(Cursor 单文件入口)

> 本文件由 [gospec](https://github.com/singchia/gospec) 自动生成,作为 **Cursor 的唯一入口**。
> 完整规范在 `~/.claude/skills/gospec/spec/` 或 `.claude/skills/gospec/spec/`。
> Cursor 已通过 `globs` 自动附加,无需用户每次选择。

## 任务路由(先看这个表,再决定要不要展开 spec/)

| 任务 | 最少必读 |
|------|---------|
| 写 HTTP / gRPC handler | `spec/03-api/proto.md` + `spec/03-api/http.md` + `spec/05-coding/errors.md` |
| 写业务逻辑 / Service | `spec/02-architecture/layering.md` + `spec/05-coding/errors.md` |
| 写 goroutine / 用锁 / 传 context | `spec/05-coding/concurrency.md` |
| 写 MySQL 模型 / DAO | `spec/04-data-model/mysql.md` |
| 写 Redis 缓存 / 分布式锁 | `spec/04-data-model/redis.md` |
| 写测试 | `spec/06-testing/unit.md` |
| 写 migration | `spec/13-database-migration/migration.md` |
| 加日志 / 指标 / 追踪 | `spec/10-observability/{logging,metrics,tracing}.md` |
| 实现登录 / 鉴权 | `spec/11-security/auth.md` |
| 写 PRD / RFC / ADR / HLD | `docs/templates/` 对应模板 |
| PR 自查 | `spec/07-code-review.md` |

## 核心约束(不可违反,无需打开 spec 也要遵守)

### 架构
- 单服务:`cmd → web → controlplane → repo → model`,禁止跨层
- monorepo:`internal/<domain>` 之间禁止直接 import,走 API / 事件 / `internal/shared/`
- 接口在消费方定义,禁止循环依赖
- 依赖通过构造函数注入

### 编码
- 禁止 `_ = fn()` 忽略错误
- 共享状态必须加锁,测试必须 `-race`
- 错误用 `%w` 包装;不重复记录
- 涉及 IO 的函数第一个参数 `context.Context`
- `init()` 仅做注册(pprof / collector / driver),禁止 IO 或可能 panic
- 避免 `any` / `interface{}` 出现在公共 API 边界

### API
- 所有变更先改 `.proto`,禁止改生成代码
- Handler 必须有 Swagger 注释(`@Summary` / `@Router` / `@Success`)
- 响应统一 `{code, message, data}`
- 破坏性变更走新版本

### 测试
- 新功能必须有单元测试
- CI 强制 `-race`
- E2E 必须清理数据

### Git
- 提交格式:`<type>(<scope>): <desc>`
- 禁止提交敏感信息
- 禁止 force push main/master

### 可观测性
- 暴露 `/healthz` `/readyz` `/metrics`
- 日志结构化 + `trace_id`
- 高基数字段(user_id / email / url)禁止做 Prometheus label
- 敏感字段禁止明文入日志

### 安全
- 密码 bcrypt / argon2id,禁止 MD5 / SHA1
- SQL 全部参数化
- 密钥禁止进代码 / 镜像 / 日志
- 容器以非 root 运行
- 多租户接口强制 `tenant_id` 过滤

### 运维
- 任何变更必须有回滚方案
- 告警必须配 Runbook 链接
- 高风险变更走金丝雀 / feature flag
- P0 / P1 事故必须产 blameless postmortem

### 数据存储
- **MySQL**:schema 变更走 migration;大表用在线 DDL;变更兼容滚动发布
- **Redis**:所有 key 必须 TTL;禁止大 key(value > 10KB / 集合 > 5000);分布式锁有 owner 校验
- **ClickHouse**:必须 Replicated;写入批量;ORDER BY 低基数到高基数
- **InfluxDB**:tag 低基数;bucket 必须 retention
- PII 字段加密存储

## 输出语言

默认中文(代码注释 / 文档 / commit message)。
8 changes: 4 additions & 4 deletions docs/templates/project-agents-template.md
Original file line number Diff line number Diff line change
Expand Up @@ -46,13 +46,13 @@
- 每个目录都被 CODEOWNERS 覆盖

### 编码
- 禁止 `_ = fn()` 忽略错误
- 禁止 `_ = fn()` 忽略错误(确实想丢弃必须注释说明)
- 共享状态必须加锁,测试必须带 `-race`
- 错误用 `%w` 包装;不重复记录(要么处理要么传播)
- 所有涉及 IO 的函数第一个参数为 `context.Context`
- 禁止 `init()` 函数(除 pprof 注册等特殊场景)
- 禁止全局可变变量
- 禁止裸 `interface{}`
- `init()` 仅允许做注册(pprof / metrics collector / driver),禁止做 IO 或可能 panic
- 禁止全局可变变量(只读单例 / collector 除外)
- 避免 `any` / `interface{}` 出现在公共 API 边界(解码 / SDK 适配等不可避免时就近注释)

### API
- 所有 API 变更先更新 `.proto`,禁止改生成代码
Expand Down
78 changes: 63 additions & 15 deletions scripts/install.sh
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
#!/usr/bin/env bash
# install.sh — 在你的 Go 项目根目录运行,一行命令安装并激活 gospec
#
# 它做两件事
# 它做几件事
# 1. 安装 gospec skill 到 ~/.claude/skills/gospec/(如果还没装)
# 2. 在当前目录创建 AGENTS.md,让任何 AI agent 打开本项目都能识别 gospec
# 2. 在当前目录创建 AGENTS.md(Codex / Cline / Cursor 等通用入口)
# 3. 检测 Cursor,自动落 .cursor/rules/gospec.mdc
# —— 让 Cursor 通过 globs 自动附加,避免每次让用户挑选
# 4. 检测 Claude Code 项目级 .claude/,可选项目级 skill 软链
#
# 用法(远程,一行命令):
# cd your-go-project
Expand All @@ -15,13 +18,19 @@
#
# 项目级安装(仅对当前项目生效):
# SKILL_DIR=.claude/skills/gospec bash <(curl -sSL .../install.sh)
#
# 跳过 Cursor 落盘:
# NO_CURSOR=1 bash <(curl -sSL .../install.sh)

set -euo pipefail

REPO_URL="https://github.com/singchia/gospec.git"
SKILL_DIR="${SKILL_DIR:-$HOME/.claude/skills/gospec}"
TEMPLATE_REL="docs/templates/project-agents-template.md"
TARGET="./AGENTS.md"
CURSOR_TEMPLATE_REL="docs/templates/cursor-rule-template.mdc"
TARGET_AGENTS="./AGENTS.md"
TARGET_CURSOR_DIR="./.cursor/rules"
TARGET_CURSOR="$TARGET_CURSOR_DIR/gospec.mdc"

echo "📦 gospec 安装"
echo ""
Expand All @@ -31,6 +40,16 @@ echo ""
# ────────────────────────────────────────────────────────
if [[ -f "$SKILL_DIR/SKILL.md" ]]; then
echo "✓ gospec skill 已安装在 $SKILL_DIR"
# 可选:检测远端有更新提示用户 update(不强制)
if command -v git >/dev/null 2>&1 && [[ -d "$SKILL_DIR/.git" ]]; then
if git -C "$SKILL_DIR" fetch --quiet origin 2>/dev/null; then
BEHIND=$(git -C "$SKILL_DIR" rev-list --count HEAD..origin/main 2>/dev/null || echo 0)
if [[ "$BEHIND" != "0" ]]; then
echo "⚠ 本地 gospec 落后远端 $BEHIND 个 commit,更新:"
echo " git -C $SKILL_DIR pull --ff-only"
fi
fi
fi
else
if ! command -v git >/dev/null 2>&1; then
echo "❌ git 未安装,无法继续"
Expand All @@ -46,8 +65,9 @@ fi
# Step 2: 校验模板存在
# ────────────────────────────────────────────────────────
TEMPLATE_FULL="$SKILL_DIR/$TEMPLATE_REL"
CURSOR_TEMPLATE_FULL="$SKILL_DIR/$CURSOR_TEMPLATE_REL"
if [[ ! -f "$TEMPLATE_FULL" ]]; then
echo "❌ 模板未找到:$TEMPLATE_FULL"
echo "❌ AGENTS 模板未找到:$TEMPLATE_FULL"
echo " gospec 安装可能损坏或版本过旧,尝试:"
echo " rm -rf $SKILL_DIR && bash $0"
exit 1
Expand All @@ -56,22 +76,50 @@ fi
# ────────────────────────────────────────────────────────
# Step 3: 在当前目录创建 AGENTS.md
# ────────────────────────────────────────────────────────
if [[ -f "$TARGET" ]]; then
BACKUP="$TARGET.bak.$(date +%Y%m%d%H%M%S)"
echo "⚠ $TARGET 已存在,备份为 $BACKUP"
cp "$TARGET" "$BACKUP"
if [[ -f "$TARGET_AGENTS" ]]; then
BACKUP="$TARGET_AGENTS.bak.$(date +%Y%m%d%H%M%S)"
echo "⚠ $TARGET_AGENTS 已存在,备份为 $BACKUP"
cp "$TARGET_AGENTS" "$BACKUP"
fi
cp "$TEMPLATE_FULL" "$TARGET_AGENTS"
echo "✓ AGENTS.md 已创建:$(pwd)/AGENTS.md(Codex / Cline / 通用 agent 入口)"

# ────────────────────────────────────────────────────────
# Step 4: 为 Cursor 落 .cursor/rules/gospec.mdc
# (单文件 + globs 自动附加,避免 Cursor 每次让用户选择)
# ────────────────────────────────────────────────────────
if [[ "${NO_CURSOR:-0}" == "1" ]]; then
echo "⏭ 跳过 Cursor 规则(NO_CURSOR=1)"
elif [[ ! -f "$CURSOR_TEMPLATE_FULL" ]]; then
echo "⚠ Cursor 模板未找到,跳过:$CURSOR_TEMPLATE_FULL"
else
mkdir -p "$TARGET_CURSOR_DIR"
if [[ -f "$TARGET_CURSOR" ]]; then
BACKUP="$TARGET_CURSOR.bak.$(date +%Y%m%d%H%M%S)"
echo "⚠ $TARGET_CURSOR 已存在,备份为 $BACKUP"
cp "$TARGET_CURSOR" "$BACKUP"
fi
cp "$CURSOR_TEMPLATE_FULL" "$TARGET_CURSOR"
echo "✓ Cursor 规则已创建:$TARGET_CURSOR"
echo " (globs 自动附加 .go / .proto / Dockerfile / migration,无需每次手动选)"
fi

cp "$TEMPLATE_FULL" "$TARGET"
# ────────────────────────────────────────────────────────
# Step 5: 提示 Claude Code 项目级安装
# ────────────────────────────────────────────────────────
if [[ -d ".claude" && ! -d ".claude/skills/gospec" ]]; then
echo ""
echo "💡 检测到 .claude/,如需项目级安装(不影响其他项目):"
echo " SKILL_DIR=.claude/skills/gospec bash $0"
fi

echo "✓ AGENTS.md 已创建:$(pwd)/AGENTS.md"
echo ""
echo "───────────────────────────────────────────────"
echo "下一步:"
echo " 1. 检查 AGENTS.md 内容,按需调整核心约束"
echo " 1. 检查 AGENTS.md / .cursor/rules/gospec.mdc 内容,按需调整"
echo " 2. 提交到 git:"
echo " git add AGENTS.md"
echo " git commit -m 'chore: add gospec AGENTS.md'"
echo " 3. 任何 AI agent(Claude Code / Cursor / Cline / Codex)"
echo " 打开本项目都会读到 AGENTS.md 并加载 gospec 规范"
echo " git add AGENTS.md .cursor/rules/gospec.mdc"
echo " git commit -m 'chore: add gospec rules'"
echo " 3. 任何 AI agent(Claude Code / Cursor / Cline / Codex / Gemini CLI)"
echo " 打开本项目都会自动加载 gospec 规范"
echo "───────────────────────────────────────────────"
Loading
Loading