@nathan33/nao-skill 0.21.1 → 0.21.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -22,11 +22,13 @@ description: 派发消息与回执模板(按需,派发/回执前读取)
22
22
  ## 回执 done(lite):默认(无阻塞、无风险的常规任务,单行)
23
23
 
24
24
  ```text
25
- [编号] done(lite) | <role> | 清单:未过<项 或 无> | 测试:<命令> exit=<n> <文件数>/<例数>/<红数> | 变更:<f1,f2(>3 个写前 3 + "等 N 个")> | 遗留:<无 | n 项 → 台账|tasks-state|Issue|接受(到期)> | commit=<短 hash 或 —> | 详情:docs/reports/<编号>.md
25
+ [编号] done(lite) | <role> | 清单:未过<项 或 无> | 测试:HEAD=<跑门禁时短 sha> · 工作区=<静默|非静默(原因)> · <命令> exit=<n> <文件数>/<例数>/<红数>(每个计数数字后跟「命令 → 输出」) | 变更:<f1,f2(>3 个写前 3 + "等 N 个")> | 遗留:<无 | n 项 → 台账|tasks-state|Issue|接受(到期)> | commit=<交付提交短 hash,≠ 门禁 HEAD;无则 —> | 详情:docs/reports/<编号>.md
26
26
  ```
27
27
 
28
28
  > `commit=`(仅 git 流程任务):work 分支最新提交短 hash,便于 PM 核对归因(commit.md 约定);无 push/纯文档任务写 `commit=—`。
29
29
  > `遗留:` 取值枚举 `无 | <n> 项 → <台账|tasks-state|Issue|接受(到期)>`;零遗留写 `无`,禁省略字段(三出口定义见 @.agents/skills/task-completion.md §四)。
30
+ > **`测试:` 段三件套(静默工作区 / HEAD sha / 命令 + 输出)口径单源见 @.agents/common/output-format.md「回执硬性」第 3 条** —— 本文件只给可复制形态,**不复写三件套全文**(PM / QA / RD 三侧同源)。
31
+ > **`HEAD=` ≠ `commit=`**:前者 = **跑门禁时**的 HEAD(数字的归属),后者 = **交付提交**(归因);门禁后又补提交时两者必然不同 —— 混用即「同一命令两种结论」的根源。
30
32
 
31
33
  ## 回执 done(full):出现阻塞/风险/需决策,或 PM 指定
32
34
 
@@ -35,8 +37,8 @@ description: 派发消息与回执模板(按需,派发/回执前读取)
35
37
  摘要:≤150字
36
38
  清单:已核对 checklists/<role>.md;未过:<项 或 无>
37
39
  变更:<文件/模块级>
38
- 测试:<命令 + exit code + 文件数/例数/红数(或错误数)>
39
- commit:<短 hash 或 —>
40
+ 测试:HEAD=<跑门禁时短 sha> · 工作区=<静默(`git status --porcelain` 空 + 本会话独占 worktree)| 非静默(原因)> · <命令> exit=<n> · <文件数>/<例数>/<红数>(每个计数数字后跟「命令 → 输出」)
41
+ commit:<交付提交短 hash(**≠ 门禁 HEAD**;本分支最新交付提交)或 —>
40
42
  遗留:<无 | n 项 → 台账|tasks-state|Issue|接受(到期)>(每条附出处与 owner;接受类必须带到期日)
41
43
  风险/阻塞:<无 或 列出>
42
44
  详情:<路径>
@@ -107,7 +107,7 @@ description: PM 交付核对清单(按需,交付/派发前读取)
107
107
  - [ ] `gh` 可用则已用 `gh`,降级已注明;发布后事实(含 `tasks-state` 版本/Tag 行)的**落地时机与工作区纪律见 `github-flow.md` BR5**(单源指针,本清单不复写命令细节)
108
108
  - [ ] 任务 DoD 四类已随**开工确认卡**逐任务实例化(产物路径 / 可执行验证判据 / 遗留项 / 交接),验收按同一份核
109
109
  - [ ] 回执含 `遗留:` 字段且遗留项已**三出口**收口(关闭 / 接受含到期日 / 转办;零遗留显式「无」,可执行项已进 `tasks-state` 待派发队列)
110
- - [ ] **计数类数字必须 PM 自证一条命令** —— 用例数 `bash tests/t4/run.sh --list | tail -n +2 | wc -l`(**`--list` 首行是表头**,裸 `wc -l` = 19 会多算 1 —— 这条命令本身也已实测校准)· 断言数(run.sh 汇总 PASS 数或 `grep -c '\[PASS\]'`)· `files=` 口径(`check` 输出 vs `find "$NAO_SKILLS/.agents" -type f | wc -l`);**回执与命令输出不一致时以命令为准**,并当场订正回执/文档(来源:L1 复盘 `docs/reports/2026-11-01-T536-retro.md`)
110
+ - [ ] **计数类数字必须自证一条命令** —— 用例数 / 断言数 / `files=` / 行数的**取数命令单源见 `tests/README.md`「取数命令四条」**(本清单**不复写命令**;PM / QA / RD 三侧同源);回执须同时给 **命令 + 输出 + HEAD sha + 静默工作区状态**(三件套见 @.agents/common/output-format.md「回执硬性」第 3 条);**回执与命令输出不一致时以命令为准**,并当场订正回执/文档(来源:L1 复盘 `docs/reports/2026-11-01-T536-retro.md`)
111
111
  - [ ] 通过上面全部红线
112
112
 
113
113
  ## 会话回收 / 收窗核对(验收通过后 / 手工关窗前)
@@ -20,7 +20,7 @@ description: 测试工程师交付核对清单(按需,交付前读取)
20
20
  - [ ] 只测主路径,无异常/边界覆盖?
21
21
  - [ ] 未 Verify 就关闭缺陷?
22
22
  - [ ] 定位被测代码/受影响测试未走三段阶梯:原生入口 `codegraph_explore`(需插件 + CLI + 索引齐备)→ CLI → `grep -rn` + 行段(口径见 @.agents/skills/codegraph.md)?(回退 grep 需注明原因)
23
- - [ ] 未跑**全范围门禁**(不是子目录)并回执精确数字?(PM 不重复跑,回执数字即验收唯一依据;全范围口径见项目 `AGENTS.md`;**计数类数字(例数/文件数/断言数)口径单源见 `tests/README.md`「计数可见」**,不以最大编号推断)
23
+ - [ ] 未跑**全范围门禁**(不是子目录)并回执精确数字?(PM 不重复跑,回执数字即验收唯一依据;全范围口径见项目 `AGENTS.md`;**计数类数字(例数/文件数/断言数/行数)取数命令口径单源见 `tests/README.md`「取数命令四条」**,不以最大编号推断;回执须带 **HEAD sha + 静默工作区**(`git status --porcelain` 空、无并行会话同 worktree 跑门禁),缺任一项该数字不得作验收依据 —— 三件套见 @.agents/common/output-format.md「回执硬性」第 3 条)
24
24
  - [ ] 视觉/UI 呈现类验证启动了浏览器自动化(无头浏览器/截图对比)?(应产出用户验收清单交用户人工,见 skills/test-design.md「视觉/UI 呈现验证」)
25
25
  - [ ] 含 UI 呈现的交付未产出用户验收清单(测什么/怎么操作/预期结果/对应 AC)?
26
26
 
@@ -16,7 +16,7 @@ description: 工程基座交付核对清单(按需,交付前读取)
16
16
  - [ ] **不自验自己的守卫**(验收由 `qa`/`pm` 独立执行)
17
17
  - [ ] 不写死仓库名/相对路径/包管理器(跨项目兼容)
18
18
  - [ ] 未改项目 `AGENTS.md` 红线、业务源码/测试断言、他人未提交文件
19
- - [ ] 全范围门禁 rc=0 且回执**精确数字**(命令 + exit code + 条数/文件数)
19
+ - [ ] 全范围门禁 rc=0 且回执**精确数字**(命令 + exit code + 条数/文件数);**计数类数字(用例数/断言数/`files=`/行数)取数命令单源见 `tests/README.md`「取数命令四条」**(本清单不复写命令),回执须带 **HEAD sha + 静默工作区**(`git status --porcelain` 空 + 无并行会话同 worktree 跑门禁),缺项则该数字不作验收依据
20
20
 
21
21
  ## 幂等 / 权限 / 自证 速查
22
22
 
@@ -87,7 +87,7 @@ bash .agents/scripts/nao-fleet.sh check
87
87
  - **两级回执**(模板见 @.agents/checklists/comm-templates.md,回执前读取):默认 `done(lite)` 单行(含门禁精确数字);**出现阻塞/风险/需决策或 PM 指定时用 `done(full)`**。前缀 `[编号] done` 不变(PM 追讨/红线均按 `done` 匹配)。
88
88
  - 每次派发的任务(含架构评审)**必须以终态回执结束**:按 @.agents/checklists/comm-templates.md `[编号] done(lite|full) | <role>`,经 intercom `send` 回 PM。
89
89
  - **回执 = 已核对清单**:回执须声明已读 `checklists/<role>.md` 并逐项核对(未过项必须列出);未核对不回执。
90
- - **回执「测试」字段 = 全量门禁精确数字(硬性)**:必须给 `命令 + exit code + 文件数/例数/红数(或错误数)`;**只跑子目录、或只写「pass」不算回执** → PM 打回。**跑子目录不算验收**:全范围口径见项目 `AGENTS.md`。
90
+ - **回执「测试」字段 = 全量门禁精确数字(硬性)**:必须给 `命令 + exit code + 文件数/例数/红数(或错误数)`,并含**三件套**(**静默工作区** / **HEAD sha** / **命令 + 输出** —— 口径单源见 @.agents/common/output-format.md「回执硬性」第 3 条,本处不复写;可复制形态见 @.agents/checklists/comm-templates.md);**只跑子目录、或只写「pass」不算回执** → PM 打回。**跑子目录不算验收**:全范围口径见项目 `AGENTS.md`。
91
91
  - 短消息(≤150 字摘要 + 结论/决策点 + 详情落盘路径);**禁止**把长报告全文 `send` 污染线程(output-format「反模式」)。
92
92
  - arch 评审回执至少含:可行性结论、ADR 路径、待 PM 拍板决策点。
93
93
  - `send` 失败(目标离线 / 会话不存在)→ 尝试 `ask`;仍失败 → 降级交付并注明,见「降级」。
@@ -30,7 +30,11 @@ description: 全角色共用输出与沟通红线(常驻;模板按需)
30
30
 
31
31
  1. 前缀 `[编号] done` 不变(PM 追讨与红线均按 `done` 匹配);**派发时由 PM 声明级别,未声明默认 `done(lite)`**。
32
32
  2. 回执即声明已读 `checklists/<role>.md` 并逐项核对(未过项必须列出)——**未核对不回执**。
33
- 3. 「测试」必须给**全量门禁精确数字**(命令 + exit code + 文件数/例数/红数或错误数);只跑子目录或只写「pass」不算回执 —— PM 打回(见 intercom-protocol「终态回执」)。
33
+ 3. 「测试」必须给**全量门禁精确数字**(命令 + exit code + 文件数/例数/红数或错误数);只跑子目录或只写「pass」不算回执 —— PM 打回(见 intercom-protocol「终态回执」)。**三件套缺一即打回**:
34
+ - **静默工作区**:门禁须在**静默工作区**执行 —— `git status --porcelain` 为空,且同一 worktree **无其他会话正在跑门禁**。不满足 ⇒ 回执显式标注「非静默(原因)」,**该数字不得作为验收依据**。
35
+ - **HEAD sha**:必须记跑门禁时的 `HEAD`(短 sha 可);无 HEAD 的数字不可复核 —— 「同一命令两种结论」时无法判定是代码差异还是环境差异。
36
+ - **命令 + 输出**:每个计数类数字一律给「**命令 + 输出**」(输出原文,或摘要 + 可直接复跑的命令),**禁「我数了 N」**;用例数 / 断言数 / `files=` / 行数的取数命令**单源见 `tests/README.md`「取数命令四条」**,本处不复写命令。
37
+ - **不合格回执(据此打回)**:`测试:npm test 通过,t4 21 个用例全绿` —— 无 HEAD、无命令、无工作区状态,且「21」来自最大编号(实测 20)⇒ **打回**,补齐 HEAD + 静默工作区状态 + 命令与输出后重报。
34
38
  4. **有阻塞/风险/需决策 → 必须 `done(full)`**(`lite` 不得吞掉需 PM 拍板的事);详细全文落盘 `docs/reports/<编号>.md`,**禁止**把长报告贴进线程。
35
39
 
36
40
  ## 反模式(禁止)
@@ -22,6 +22,9 @@ description: 发版说明写作规范(面向用户、说人话;写 / 验收
22
22
  4. **口径与落盘一致**:`docs/releases/<version>.md` 是权威落盘;`gh release create --notes-file <该文件>` 与之一同源,禁止两处各写各的。
23
23
  5. **Release 标题 = 裸版本号 `vX.Y.Z`**(仅版本号,可带预发布后缀如 `-beta.1`;不得含描述性文本 / `—`、`·`、`:` 副题 / 编号 / 日期)。
24
24
  - 标题**不用构思**:一句话概括等描述性内容**一律置于正文首段「本次更新」**(见 §二.1);`--title` 只写 `<tag>` 本身。
25
+ 6. **状态行禁止在 npm 核验前写「已核验」。** 发布说明顶部「状态」行只能写「**待核验**」;顺序固定 = 先「待核验」→ 发布后按**唯一判据**核验(`dist-tags.latest` = 该版本 + `dist.integrity` 与本地 `npm pack` tarball **逐字节一致**)→ 再回填实测值(`latest` + integrity 全文 + tarball 字节数)。
26
+ - 理由:未核验就写「已核验」在写下那一刻即**假陈述**(v0.20.4 实测:QA 复核时 registry 仍是 0.20.3)。
27
+ - 与 §一.2 不冲突:**状态行属元数据行,不受「内部信息下沉技术细节」禁令约束** —— `dist.integrity` 全文 + tarball 字节数必须在该行置顶可见,不得下沉。
25
28
 
26
29
  ## 二、建议结构(顺序固定,用不上的段可省)
27
30
 
@@ -32,6 +35,7 @@ description: 发版说明写作规范(面向用户、说人话;写 / 验收
32
35
  5. **📦 更小更快** —— 体积 / 性能 / 启动等可感知收益。
33
36
  6. **技术细节(可略过)** —— 编号 / 哈希 / 依赖版本 / 门禁数字 / 文档链接。
34
37
 
38
+ - **状态行(骨架:标题下第一行)**:`- 状态:已发布(…)· 更新:YYYY-MM-DD · Owner:<角色>`;npm 未核验前**一律写「待核验」**,核验后再回填实测值(`latest` + integrity 全文 + tarball 字节数),口径见 §一.6。
35
39
  - **已知问题出口**:会影响用户 ⇒ 写入「⚠️ 请留意」;否则下沉「技术细节(可略过)」。
36
40
  - **纯内部仓**(无面向用户交付)可省略第 2–5 段的「面向用户」写法,但**结构保留**(仍按「概括 → 变化 → 技术细节」分层)。
37
41
  - **排版**:本文件与其他文档同受 @.agents/checklists/deliverable-docs.md 「默认不使用表格」约束 —— release notes 正文尤其不要用表格。
@@ -46,17 +50,19 @@ description: 发版说明写作规范(面向用户、说人话;写 / 验收
46
50
  ## 四、发布前核对
47
51
 
48
52
  - [ ] 正文最前有面向用户的**「本次更新」**段(用户看得懂)。
49
- - [ ] 正文**无**编号 / 哈希 / 文件名 / 函数名 / 内部属性名 / 测试例数 / 守卫名 / 内部模块名。
53
+ - [ ] 正文**无**编号 / 哈希 / 文件名 / 函数名 / 内部属性名 / 测试例数 / 守卫名 / 内部模块名(状态行除外,见 §一.6)。
50
54
  - [ ] 行为变更写了**用户视角的后果**(不是内部机制)。
51
55
  - [ ] 结构完整(一句话 → 变化 → 技术细节);内部信息集中在「技术细节」段。
52
56
  - [ ] 正文**未使用表格**(改用有序 / 无序列表;见 @.agents/checklists/deliverable-docs.md)。
53
57
  - [ ] `docs/releases/<version>.md` 与 GitHub Release 正文同源。
54
58
  - [ ] Release 标题是**裸 `vX.Y.Z`**(无描述性文本 / 副题;见 §一.5)。
59
+ - [ ] 状态行是「**待核验**」而非「已核验」(npm 未核验前;核验后已回填实测值 —— 口径见 §一.6)。
55
60
 
56
61
  ## 五、红线
57
62
 
58
63
  - [ ] 只写内部机制、用户看不懂?
59
- - [ ] 正文里直接出现编号 / 哈希 / 类名 / 属性名 / 测试例数?
64
+ - [ ] 正文里直接出现编号 / 哈希 / 类名 / 属性名 / 测试例数(状态行除外,见 §一.6)?
60
65
  - [ ] 没有面向用户的「本次更新」段,或它不在最前?
61
66
  - [ ] 盘上 release notes 与 Release 正文两处不一致?
62
67
  - [ ] Release 标题带了描述性文本 / 分隔副题(应为裸 `vX.Y.Z`)?
68
+ - [ ] **发布说明状态行在 npm 核验前写「已核验」**(即视为违规;依据 v0.20.4 假陈述 · QA P1,口径见 §一.6)?
@@ -100,7 +100,15 @@ TMUX_MIN_PANE_WIDTH="${NAO_TMUX_MIN_PANE_WIDTH:-$TMUX_MIN_PANE_WIDTH_DEFAULT}"
100
100
  # T517:派生宿主窗口 ID(归一化 @<window_id>;空 = 定位失败 ⇒ 该角色 pane warn+skip,禁无 -t 续建)
101
101
  HOST_WINDOW=""
102
102
  # T536:本轮真正创建成功的 pane 数(>0 ⇒ ensure 收尾打印**恰一行**就绪提示;跳过/失败分支恒 0,BR3/AC4)
103
+ # T539:三态计数(成功 / 跳过 / 失败)—— 每个 ensure 目标恰落一类,合计 = 目标数(BR3 计数守恒)
103
104
  SPAWN_OK=0
105
+ SPAWN_SKIP=0
106
+ SPAWN_FAIL=0
107
+ # T539/BR2:spawn_tmux 的**显式**结果契约(返回值;调用方禁用「没打印就是成功」这类隐式约定):
108
+ # 0 = 成功(pane 已创建)· 2 = 跳过(宿主窗口未解析,未创建)· 3 = 失败(split-window 非 0,未创建)
109
+ SPAWN_RC_OK=0
110
+ SPAWN_RC_SKIP=2
111
+ SPAWN_RC_FAIL=3
104
112
  # check 输出契约:默认摘要 2 行(摘要行 + codegraph 状态行,四态之一),-v 展开完整报告(六态全展开);失败始终展开
105
113
  VERBOSE=false
106
114
  # close 的在跑 turn 判定(pi 默认状态行:Working (esc to interrupt) / Thinking... / Retrying / Compacting)
@@ -1059,17 +1067,20 @@ spawn_tmux() {
1059
1067
  local wrapped="bash -lc $(printf %q "$inner")"
1060
1068
  # T517:目标显式化——HOST_WINDOW 解析失败时此处已由解析处 warn(每 run 一次),
1061
1069
  # 跳过该 pane;禁止无 -t 续建(tmux 会落「当前窗口」= 用户视图,即缺陷根因)。
1062
- [[ -n "$HOST_WINDOW" ]] || return 0
1070
+ # T539:显式回报「跳过」(不再用 return 0 冒充成功)。
1071
+ [[ -n "$HOST_WINDOW" ]] || return "$SPAWN_RC_SKIP"
1063
1072
  # 窄窗口/宿主上限会让 split-window 失败(no space for new pane,含宿主窗已关竞态);
1064
1073
  # 捕获后 warn 并继续,不因单个 pane 失败中断整轮 ensure。
1074
+ # T539:显式回报「失败」;两条 warn 是诊断信息,保留不合并。
1065
1075
  local serr
1066
1076
  if ! serr=$(tmux split-window -h -t "$HOST_WINDOW" "$wrapped" 2>&1); then
1067
1077
  warn "pane 创建失败(宿主窗口 $HOST_WINDOW 过窄/已关或已达上限):${serr:-<no message>}"
1068
1078
  warn " 已跳过该 pane,其余角色继续拉起;可放大窗口后重跑 ensure"
1069
- return 0
1079
+ return "$SPAWN_RC_FAIL"
1070
1080
  fi
1071
- SPAWN_OK=$((SPAWN_OK + 1)) # T536:真创建成功才计数(就绪提示的唯一开关)
1072
- apply_tmux_layout
1081
+ # 布局是尽力而为(内部各 tmux 调用已 || true);布局成败不影响「pane 已创建」这一结果。
1082
+ apply_tmux_layout || true
1083
+ return "$SPAWN_RC_OK"
1073
1084
  }
1074
1085
 
1075
1086
  # 组装系统提示文件:角色卡 + 环境锚点(本机绝对路径,供跨仓库会话解析 @ 引用失败时兜底)
@@ -1102,9 +1113,17 @@ spawn_one() {
1102
1113
  # 不用 setsid:macOS 无该 bin,`… || true` 会静默跳过清理(BR1 缩水)。清理窗口 60s 不缩短。
1103
1114
  bash -c 'sleep 60; rm -f -- "$1"' _ "$prompt_file" >/dev/null 2>&1 </dev/null & disown 2>/dev/null || true
1104
1115
 
1105
- # 拉起(pane 级失败 = warn + 跳过该角色,D-A);成功后打印「已拉起」
1106
- spawn_tmux "$name" "$inner"
1107
- log "[tmux] 已拉起 $name @ $repo${model:+(model=$model)}(layout=$TMUX_LAYOUT)"
1116
+ # 拉起:spawn_tmux 以**显式三态**回报(T539/BR2);每目标恰一行结果行:
1117
+ # 成功 → 唯一一条 `[tmux] 已拉起 …`(内容逐字不变,BR1)· 跳过/失败 → 不打印成功行(BR2)。
1118
+ # `|| rc=$?` 是 set -e 下的必需写法(|| 列表豁免 errexit);函数返回值即结果契约。
1119
+ local rc=0
1120
+ spawn_tmux "$name" "$inner" || rc=$?
1121
+ case "$rc" in
1122
+ "$SPAWN_RC_OK") SPAWN_OK=$((SPAWN_OK + 1))
1123
+ log "[tmux] 已拉起 $name @ $repo${model:+(model=$model)}(layout=$TMUX_LAYOUT)" ;;
1124
+ "$SPAWN_RC_SKIP") SPAWN_SKIP=$((SPAWN_SKIP + 1)) ;;
1125
+ *) SPAWN_FAIL=$((SPAWN_FAIL + 1)) ;; # 3 = fail;未知值按失败处理(宁可少报成功)
1126
+ esac
1108
1127
  }
1109
1128
 
1110
1129
  # ---------------------------------------------------------------------------
@@ -2055,6 +2074,7 @@ cmd_ensure() {
2055
2074
  if (( ! seen )); then codegraph_state "$repo" 1 "$(basename "$repo")"; cg_done+=("$key"); fi
2056
2075
  if [[ "$force" != "true" ]] && running "$disp" "$repo"; then
2057
2076
  warn "$disp 已在运行(终端标题/名册命中),跳过;确需重开请加 --force"
2077
+ SPAWN_SKIP=$((SPAWN_SKIP + 1)) # T539/BR3:跳过也计入摘要(且不加成功行)
2058
2078
  continue
2059
2079
  fi
2060
2080
  if [[ -n "${t_cards[$i]}" ]]; then
@@ -2063,10 +2083,10 @@ cmd_ensure() {
2063
2083
  spawn_one "$disp" "$repo" "$model"
2064
2084
  fi
2065
2085
  done
2066
- # T536/BR3/AC4:仅当本轮真拉起过 pane 才打印**恰一行**就绪提示;
2067
- # 跳过(已在运行)/失败(无宿主窗口、分屏失败)分支不打印;既有行内容与顺序不变(只追加末尾一行)。
2068
- if (( SPAWN_OK > 0 )); then
2069
- log "已拉起 ${SPAWN_OK} 个会话;就绪后在线状态用 nao-fleet.sh status 查看"
2086
+ # T536/BR3/AC4 + T539/BR3:**恰一行**摘要,三类计数(成功/跳过/失败);三类全 0 不打印(与现状一致)。
2087
+ # 前缀「已拉起 N 个会话」保留(既有断言与用户习惯依赖),计数细化追加在括号内(BR6 旧→新对照见 T539 报告)。
2088
+ if (( SPAWN_OK + SPAWN_SKIP + SPAWN_FAIL > 0 )); then
2089
+ log "已拉起 ${SPAWN_OK} 个会话(成功 ${SPAWN_OK} / 跳过 ${SPAWN_SKIP} / 失败 ${SPAWN_FAIL});就绪后在线状态用 nao-fleet.sh status 查看"
2070
2090
  fi
2071
2091
  }
2072
2092
 
@@ -69,6 +69,7 @@ PM 在**立项 / 终签 / 发布**时读取;RD 在**起分支 / 开 PR / 合
69
69
  - 门禁:AC 全过 + 验收闭环 + main 门禁全绿 + 工作区干净 + PR 已合并。
70
70
  - **发布前置(严格闸门 · 双环境)**:若仓库提供 `test:t4:full:dual` 脚本,发布前须先 `npm run test:t4:full:dual` **rc=0**(**两组**= `$TMUX_PANE` 已设 / `env -u TMUX_PANE`;判据 = **两组 SKIP 计数与 DEGRADE 计数均为 0,且非白名单 NOTE 计数为 0**,`SKIP`/`DEGRADE`/非白名单 `NOTE` 即 FAIL)。仅有 `test:t4:full`(单环境)的仓库退用 `npm run test:t4:full` rc=0;双环境 gate 误红时可临时回落单环境并记台账。
71
71
  - **优先 `gh`**:`gh release create <tag> --title "vX.Y.Z" --notes-file docs/releases/<version>.md`(**标题口径(强约束):@.agents/common/release-notes.md** —— 标题仅裸版本号,描述进正文首段)。
72
+ - **`gh release create <tag> --target <短 sha>` 不可用(两次实测:v0.21.0 / v0.21.1)**:会报 `tag_name is not a valid tag` / `target_commitish is invalid`。正确路径 = 先 `git tag -a <tag> -m "<说明>"` → `git push origin <tag>` → `gh release create <tag> --title <裸版本号> --notes-file <file> --verify-tag`(**不要**用 `--target` 指向未 push 的短 sha)。
72
73
  - 探测:`gh auth status` 按 **exit code** 判定(`keyring` 警告但 exit 0 **仍可用**,可 `gh api user` 复核);**不自动 `gh auth login`**(涉用户凭证)。
73
74
  - release notes 落盘 `docs/releases/<version>.md`(**写作规范(强约束):@.agents/common/release-notes.md** —— 面向用户「本次更新」置顶、内部编号 / 文件名 / 属性名一律下沉「技术细节」、正文不用表格;骨架见 @.agents/templates/release-notes.md.example)。
74
75
  - 回滚:未 push → `git tag -d`;已 push → **不删远端 tag**,改发下一个 PATCH 修正(用户明确要求才删)。
@@ -6,7 +6,11 @@
6
6
  ⛔ 自查:正文无编号 / 哈希 / 文件名 / 函数名 / 内部属性名 / 测试例数 / 守卫名 / 内部模块名;正文不要用表格。
7
7
  -->
8
8
 
9
- # 本次更新
9
+ # vX.Y.Z — <一句话总结>
10
+
11
+ - 状态:待核验 · 更新:YYYY-MM-DD · Owner:PM
12
+
13
+ ## 本次更新
10
14
 
11
15
  **<一句话概括这版最大的变化;用用户能听懂的话。>**
12
16
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nathan33/nao-skill",
3
- "version": "0.21.1",
3
+ "version": "0.21.3",
4
4
  "description": "nao 多角色 AI 开发舰队:角色卡 / 技能 / 协作协议 / 工具链,一键接入项目(pi / Claude / 任意 Agent)",
5
5
  "type": "module",
6
6
  "bin": {