Compare commits

...

3 Commits

Author SHA1 Message Date
lanrtop
8b85f49234 test(onboarding): 补 git-workflow 版本升级场景 + 修复断言版本硬编码
All checks were successful
Push & PR Check / check (push) Successful in 50s
Push & PR Check / check (pull_request) Successful in 48s
三态测试新增:v1.2.0 存量项目重跑后 git-workflow 块升至 1.3.0,
块外用户内容保留;修复 AGENTS 版本断言从硬编码 1.2.0 改为动态提取。

Rules-Applied: R07,R13
2026-07-04 10:30:38 +09:00
lanrtop
428bb02a90 chore(blueprint): T2 验收完成 — git-workflow 分支策略升级
All checks were successful
Push & PR Check / check (push) Successful in 46s
Push & PR Check / check (pull_request) Successful in 46s
2026-07-04 10:24:18 +09:00
lanrtop
ce3bc8081b feat(onboarding): git-workflow 模板分支策略升级为复杂度感知 v1.3.0
简单改动直推 main/master,功能性改动开 feat/<name> 分支 + PR,
废弃强制 dev→main 双分支模型。PR 示例 head 字段同步更新。

Rules-Applied: R13
2026-07-04 10:23:56 +09:00
3 changed files with 33 additions and 12 deletions

View File

@ -116,9 +116,10 @@
- acceptance: [Tauri command] apply_onboarding_pack(project_id) 分发 lefthook.yml 后检测并激活 hook——找到 lefthook 可执行(node_modules/.bin/ 或 PATH)→ 执行 lefthook install,OnboardingReport 新增 hook_activated 三态(activated / missing_binary / failed),missing_binary 时附安装提示;[MCP tool] verify_onboarding(project_id) → 返回检查链 JSON(模板管理块版本到位 / .git/hooks/pre-commit 含 lefthook / origin 指向 Gitea / CI workflow 文件存在 / commit_metrics 近 30 天有该项目数据),每项 pass|fail + detail,无 error 字段;[cargo test] 检查链判定逻辑纯函数化,覆盖 hook 已挂/未挂、origin 匹配/不匹配(R06/R07) - acceptance: [Tauri command] apply_onboarding_pack(project_id) 分发 lefthook.yml 后检测并激活 hook——找到 lefthook 可执行(node_modules/.bin/ 或 PATH)→ 执行 lefthook install,OnboardingReport 新增 hook_activated 三态(activated / missing_binary / failed),missing_binary 时附安装提示;[MCP tool] verify_onboarding(project_id) → 返回检查链 JSON(模板管理块版本到位 / .git/hooks/pre-commit 含 lefthook / origin 指向 Gitea / CI workflow 文件存在 / commit_metrics 近 30 天有该项目数据),每项 pass|fail + detail,无 error 字段;[cargo test] 检查链判定逻辑纯函数化,覆盖 hook 已挂/未挂、origin 匹配/不匹配(R06/R07)
- notes: 背景(2026-07-04 侦察确认)——接入包写 lefthook.yml 后从不激活,文件在 hook 死 → conventional 不强制 → 飞轮数据脏;炼境自身未踩纯因手动装过。本卡补两件事:① 分发即激活;② "消费者角色"机器化验证(分发成功 ≠ 功能生效,对应 agent-button-system.md 消费者驱动验证)。产出直接供 B4 健康诊断遵守度消费。同日发现的姊妹雷:cicd.rs PR CI 模板 pnpm lint --if-present 必挂语法已修(dc501f7,回归断言驻军) - notes: 背景(2026-07-04 侦察确认)——接入包写 lefthook.yml 后从不激活,文件在 hook 死 → conventional 不强制 → 飞轮数据脏;炼境自身未踩纯因手动装过。本卡补两件事:① 分发即激活;② "消费者角色"机器化验证(分发成功 ≠ 功能生效,对应 agent-button-system.md 消费者驱动验证)。产出直接供 B4 健康诊断遵守度消费。同日发现的姊妹雷:cicd.rs PR CI 模板 pnpm lint --if-present 必挂语法已修(dc501f7,回归断言驻军)
### 📋 T2. git-workflow 模板:分支策略升级为复杂度感知 ### ✅ T2. git-workflow 模板:分支策略升级为复杂度感知
- complexity: M - complexity: M
- status: todo - status: done
- done_note: 2026-07-04 ONBOARDING_MANAGED 块升至 v1.3.0,分支策略改为复杂度感知(简单直推/功能 feat/* + PR),PR MCP 示例 head 从 "dev" 改为 "feat/<name>"。模板升版后重跑接入包即可原位升级存量项目,UI 终验由用户走正常分发流程完成
- files: src-tauri/resources/onboarding/git-workflow.md.tmpl - files: src-tauri/resources/onboarding/git-workflow.md.tmpl
- acceptance: [Tauri command] 对已接入项目重跑接入包 → git-workflow.md ONBOARDING_MANAGED 块升至 v1.3.0,内容含「简单改动直推 main/master,功能性改动开 feat/<name> 分支 + PR」策略;PR 创建 MCP 示例 head 字段从 "dev" 改为 "feat/<name>";docs/templates/agents-meta-rules.md 不含分支策略无需同步 - acceptance: [Tauri command] 对已接入项目重跑接入包 → git-workflow.md ONBOARDING_MANAGED 块升至 v1.3.0,内容含「简单改动直推 main/master,功能性改动开 feat/<name> 分支 + PR」策略;PR 创建 MCP 示例 head 字段从 "dev" 改为 "feat/<name>";docs/templates/agents-meta-rules.md 不含分支策略无需同步
- notes: 当前模板强制 dev→main 双分支,假设了任意项目都维护常设 dev 分支,实为过度约束。复杂度感知策略(小改直推 main/master,功能性改动开 feat/* + PR)与炼境自身策略一致、与飞轮目标对齐(PR body 是意图层数据),且对单人小项目更友好——不必维护无意义的常设 dev 分支。「简单/功能性」由 agent 根据改动文件数/性质自判,无需外部蓝图标签 - notes: 当前模板强制 dev→main 双分支,假设了任意项目都维护常设 dev 分支,实为过度约束。复杂度感知策略(小改直推 main/master,功能性改动开 feat/* + PR)与炼境自身策略一致、与飞轮目标对齐(PR body 是意图层数据),且对单人小项目更友好——不必维护无意义的常设 dev 分支。「简单/功能性」由 agent 根据改动文件数/性质自判,无需外部蓝图标签

View File

@ -3,19 +3,20 @@
> 把此文件粘贴给任何 AI Agent,让它了解本项目的 git 工作方式。由炼境接入包分发。 > 把此文件粘贴给任何 AI Agent,让它了解本项目的 git 工作方式。由炼境接入包分发。
> `ONBOARDING_MANAGED` 标记块由炼境版本化管理(重跑接入包可原位升级),块外可自由补充项目特有约定。 > `ONBOARDING_MANAGED` 标记块由炼境版本化管理(重跑接入包可原位升级),块外可自由补充项目特有约定。
<!-- ONBOARDING_MANAGED_START version="1.2.0" --> <!-- ONBOARDING_MANAGED_START version="1.3.0" -->
## 分支策略 ## 分支策略
``` ```
dev ← 日常开发在这里 commit/push 简单改动 → 直接 push main/master
↓ 功能改动 → feat/<name> 分支 → PR → main/master
main ← 稳定分支,通过 PR 合入(合入时触发 CI code review)
``` ```
- 小改动可直接 push `dev` - **简单改动**(单文件 bug 修复、配置调整、文档更新):直接 push `main`/`master`
- 功能完整后开 PR(dev → main) - **功能性改动**(多文件修改、新功能、重构、接口变更):开 `feat/<功能简述>` 分支,完成后 PR 合入
- 不要直接 push `main`,除非紧急热修复 - 不维护常设 `dev` 分支——每个改动按复杂度选路径,功能分支用完即关
> **为什么**:PR body 是意图层数据(炼境从中采集 Why + 验收结论),PR CI review 是 agent 自验链的最后一环;简单改动不值得开分支的额外成本——按实际复杂度决策,不一刀切。
## Commit 规范(lefthook 强制) ## Commit 规范(lefthook 强制)
@ -81,7 +82,7 @@ PR 别攒太大(建议每 3~5 个 commit 或几百行内就开一次),否
``` ```
1. Read .claude/liangjing.json → 取出 project_id 1. Read .claude/liangjing.json → 取出 project_id
2. 调用 MCP 工具 create_pull_request: 2. 调用 MCP 工具 create_pull_request:
{ "project_id": "<id>", "head": "dev", "base": "main", { "project_id": "<id>", "head": "feat/<name>", "base": "main",
"title": "<Conventional Commits 格式>", "body": "<变更摘要>" } "title": "<Conventional Commits 格式>", "body": "<变更摘要>" }
3. 炼境内部用存储的 Gitea 凭证调 API,返回 pr_url 3. 炼境内部用存储的 Gitea 凭证调 API,返回 pr_url
``` ```

View File

@ -444,8 +444,9 @@ mod tests {
assert_eq!(agents_r.action, "skipped"); assert_eq!(agents_r.action, "skipped");
// 态二(旧版本):把版本改旧 + 块外加用户内容 → updated,块升级、用户内容保留 // 态二(旧版本):把版本改旧 + 块外加用户内容 → updated,块升级、用户内容保留
let agents_tpl_ver = extract_managed_block(TMPL_AGENTS).and_then(block_version).unwrap();
let old = agents let old = agents
.replace("version=\"1.2.0\"", "version=\"1.0.0\"") .replacen(&format!("version=\"{agents_tpl_ver}\""), "version=\"1.0.0\"", 1)
.replace("## 项目概况", "## 项目概况 .replace("## 项目概况", "## 项目概况
我的项目说明") 我的项目说明")
@ -458,11 +459,29 @@ mod tests {
let agents_r = r3.iter().find(|t| t.name == "AGENTS.md").unwrap(); let agents_r = r3.iter().find(|t| t.name == "AGENTS.md").unwrap();
assert_eq!(agents_r.action, "updated"); assert_eq!(agents_r.action, "updated");
let upgraded = std::fs::read_to_string(base.join("AGENTS.md")).unwrap(); let upgraded = std::fs::read_to_string(base.join("AGENTS.md")).unwrap();
assert!(upgraded.contains("version=\"1.2.0\""), "块应升级到模板版本"); assert!(upgraded.contains(&format!("version=\"{agents_tpl_ver}\"")), "块应升级到模板版本");
assert!(upgraded.contains("我的项目说明"), "块外用户内容(前)须保留"); assert!(upgraded.contains("我的项目说明"), "块外用户内容(前)须保留");
assert!(upgraded.contains("用户自加的章节"), "块外用户内容(后)须保留"); assert!(upgraded.contains("用户自加的章节"), "块外用户内容(后)须保留");
assert_eq!(upgraded.matches(MANAGED_START).count(), 1, "只有一个管理块"); assert_eq!(upgraded.matches(MANAGED_START).count(), 1, "只有一个管理块");
// git-workflow 版本升级验证:v1.2.0 存量项目重跑后块升级,块外内容不动
let gw_tpl_ver = extract_managed_block(TMPL_GIT_WORKFLOW).and_then(block_version).unwrap();
let gw_path = base.join("docs/ai-context/git-workflow.md");
let gw_content = std::fs::read_to_string(&gw_path).unwrap();
// 把写入的最新版本改旧,模拟存量 1.2.0 项目
let gw_old = gw_content
.replacen(&format!("version=\"{gw_tpl_ver}\""), "version=\"1.2.0\"", 1)
+ "\n## 项目自加章节\n旧有内容\n";
std::fs::write(&gw_path, &gw_old).unwrap();
let r_gw = dispatch_templates(pp);
let gw_r = r_gw.iter().find(|t| t.name == "docs/ai-context/git-workflow.md").unwrap();
assert_eq!(gw_r.action, "updated", "git-workflow 旧版本应触发 updated");
let gw_upgraded = std::fs::read_to_string(&gw_path).unwrap();
assert!(gw_upgraded.contains(&format!("version=\"{gw_tpl_ver}\"")), "git-workflow 块应升级到模板版本");
assert!(gw_upgraded.contains("功能性改动"), "新分支策略关键词应出现在升级后文件中");
assert!(gw_upgraded.contains("项目自加章节"), "块外用户内容须保留");
assert_eq!(gw_upgraded.matches(MANAGED_START).count(), 1, "只有一个管理块");
// 态三:存量文件无标记 → appended,原内容保留在上方 // 态三:存量文件无标记 → appended,原内容保留在上方
std::fs::write(base.join("AGENTS.md"), "# 手写的 AGENTS std::fs::write(base.join("AGENTS.md"), "# 手写的 AGENTS