paseo-req-kit 1.9.1 → 1.10.0-beta.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.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,41 @@
2
2
 
3
3
  每个版本分为"使用者会看到的变化"和"升级须知"。升级步骤见 [docs/guide/安装与升级.md](docs/guide/安装与升级.md)。
4
4
 
5
+ ## 1.10.0-beta.3
6
+
7
+ 从卡片开始的需求:按子系统自动选仓库、研发完成后推送分支、统计按需求方汇总。
8
+
9
+ ### 使用者会看到的变化
10
+
11
+ - **按子系统选仓库**:在仓库中运行 `/req-setup` 时可以写上这个仓库接哪个空间、哪些子系统的卡片(同一子系统有几个仓库时再写标题关键字),并在本机登记。之后 `req start --from ALM:<卡号>` 不用写 `--repo`。`req card route` 查看本机登记的仓库。
12
+ - **推送分支**(默认关闭):本机或团队配置打开 `push` 后,从卡片开始的需求在研发完成、写好提测说明后推送到 `origin` 的 `req/<卡号简称>` 分支,分支名写进卡片。不强推、不合并。
13
+ - **统计**:运行记录带上需求方和卡号,`req stats --report` 多一节"从卡片开始的需求(按需求方)",CSV 多 `requester`、`card` 两列。
14
+
15
+ ### 升级须知
16
+
17
+ - 都是可选的。推送只在 `push.enabled` 为 true、需求是从卡片开始的时候发生,并且只能在本机或团队配置中打开(ADR 0029 记录了这条对"只在本地提交"规则的放宽)。
18
+ - 新增项目配置 `cardSource`、本机文件 `~/.req-kit/card-repos.json`、状态文件可选字段 `pushed`、运行记录可选字段 `requirement.requester` 和 `requirement.source`,格式版本都不变。
19
+
20
+ ## 1.10.0-beta.2
21
+
22
+ (1.10.0-beta.1 的发布任务因一个测试的顺序问题失败,没有发布,内容相同,以 beta.2 发布。)
23
+
24
+ 从卡片开始需求:需求方在需求管理系统中写好卡片,不必有人在 Paseo 对话里发起;问题和确认通过卡片描述往来。这是"软件工厂"的第一步,定时接单器在 1.11。
25
+
26
+ ### 使用者会看到的变化
27
+
28
+ - **`req start --from <系统>:<卡号>`**:读一张卡片,建功能目录,在 Paseo 中为这个需求建一个**需求会话**。需求会话按新的无人值守手册从卡片写需求说明,把摘要、验收标准、假设和问题写进卡片描述末尾的"req-kit AI 区";需求方在"需求方回复"区回答,写"确认:同意"后它自己启动开发(自动新建工作区)。需求方自己写的描述原样保留。
29
+ - **`req card check [<卡号> | --all]`**:读需求方的回复,把新的回答、补充、描述修改和确认转给需求会话;同样的内容只转一次。`req card list` 列出本机从卡片开始的需求。
30
+ - 开发中卡片跟着走:状态按 `statusMap` 改(例如"开发中""待测试"),AI 区更新进度;方案待确认时附上方案摘要,需求方在"方案确认:"后写"同意"即可。
31
+ - 从卡片开始的需求用这张卡片,不另建卡片;项目没有指定执行方式时默认只做研发。
32
+ - 在 Paseo 中打开需求会话可以看到整个过程。
33
+
34
+ ### 升级须知
35
+
36
+ - 需要在对接配置中加上 `query`(读卡片)和 `describe`(改描述),写法见《项目定制与运行规则》"从卡片开始需求"。不用这个功能的,什么都不用改。
37
+ - **行为变化**:"只做研发"的需求在研发完成时,发给外部系统对接的事件由 `completed` 改为 `phase_done`("研发完成,待测试")。给 `phase_done` 配了状态的,这类需求的卡片会改为那个状态,而不是"完成"对应的状态。
38
+ - 功能目录新增 `source.json`、`card-source.md`、`card-ai.md`(只在从卡片开始的需求中);本机新增 `~/.req-kit/cards/`。状态文件格式不变。设计决定见 ADR 0029。
39
+
5
40
  ## 1.9.1
6
41
 
7
42
  1.9 的正式版(1.9.0 的发布任务因一个测试的时序问题失败,没有发布到 npm,内容相同,以 1.9.1 发布)。汇总 1.9.0-beta.1 到 beta.3 的全部内容(各节见下):本机的需求索引与使用统计、Paseo 插件、外部系统对接。
package/bin/req.mjs CHANGED
@@ -31,6 +31,11 @@ const HELP = `req-kit ${version}(${kitRoot})
31
31
  让 Paseo 按时间表发送需求总览(例子为每周一 9:00);取消:req digest --cancel <ID>
32
32
  req sync <需求> 把需求同步到对接的外部系统(补发失败的调用、补建卡片、更新状态)
33
33
  req integration test [需求] 只显示对接外部系统时会执行的命令,不真正调用
34
+ req start --from <系统>:<卡号> 从需求管理系统中的一张卡片开始需求(没有人开着对话也可以)
35
+ req card check [<卡号>|--all] 读取需求方在卡片中的回复,转给需求的会话
36
+ req card publish <卡号> 把需求会话写的 card-ai.md 写进卡片的 AI 区
37
+ req card list 本机从卡片开始的需求
38
+ req card route 本机接收卡片的仓库和子系统(--add <仓库> 登记)
34
39
 
35
40
  使用情况(可以在任何目录运行):
36
41
  req stats [--since 30d] [--month 2026-10]
@@ -148,7 +153,12 @@ switch (command) {
148
153
  code = node([launcher, "--approve", ...feature(rest, true)]);
149
154
  break;
150
155
  case "start":
151
- code = node([launcher, ...feature(rest, true)]);
156
+ // From a card in the requirement management system (1.10): no chat needed to begin.
157
+ if (rest.some((a) => a === "--from" || a.startsWith("--from="))) code = needTsx() ? node([tsxCli, path.join(kitRoot, "engine", "src", "card-cmd.ts"), "start", ...rest]) : 1;
158
+ else code = node([launcher, ...feature(rest, true)]);
159
+ break;
160
+ case "card":
161
+ code = needTsx() ? node([tsxCli, path.join(kitRoot, "engine", "src", "card-cmd.ts"), ...rest]) : 1;
152
162
  break;
153
163
  case "doctor":
154
164
  code = node([path.join(kitRoot, "bin", "req-doctor.mjs"), ...rest]);
@@ -77,6 +77,27 @@ spec.md 头部的"版本"与最新一节一致。
77
77
 
78
78
  `fields` 的名称来自 `cardFields`,在命令参数中写作 `{card.<字段>}`。没有写的字段用 `defaults` / `integrationDefaults` 中同名的值,都没有时这个参数和它前面的选项一起省略。
79
79
 
80
+
81
+ ## source.json、card-source.md、card-ai.md(从卡片开始的需求)
82
+
83
+ 1.10.0 起。用 `req start --from <系统>:<卡号>` 从卡片开始的需求才有。
84
+
85
+ `source.json` 由引擎维护:
86
+
87
+ | 字段 | 含义 |
88
+ | --- | --- |
89
+ | `v` | 格式版本,1 |
90
+ | `system`、`id`、`url` | 对接配置中的系统名称、卡号、链接(没有时为 null) |
91
+ | `title`、`author`、`subsystem`、`state` | 卡片的标题、提出人、子系统、状态(最近一次读取时) |
92
+ | `fetchedAt` | 开始时读取卡片的时间 |
93
+ | `sourceRepo` | 需求开始时所在的仓库(流水线之后可能把它移到自己的工作区) |
94
+ | `sessionAgentId` | 需求会话的 agent ID |
95
+ | `originalHash`、`replyHash` | 最近一次转给需求会话时,需求方的描述和回复的摘要;用来判断有没有新内容 |
96
+ | `confirmedAt`、`planConfirmedAt` | 需求方的"确认:同意""方案确认:同意"转给需求会话的时间 |
97
+ | `progress`、`publishedAt` | AI 区中的进度和最近一次写入卡片的时间 |
98
+
99
+ `card-source.md` 是卡片的副本(标题、卡号、状态、提出人、子系统,需求方的描述放在 `<card-description>` 中),由引擎在开始时和需求方修改描述后写入。`card-ai.md` 由需求会话写,是卡片 AI 区的正文(Markdown;问题用 `- Q1`、`- Q2` 编号),`req card publish` 把它写进卡片。
100
+
80
101
  ## contract.md(联合需求的接口约定)
81
102
 
82
103
  1.8.0 起,联合需求(spec 的 `- 联合开发:`)的方案设计在主仓库写入:每个接口一节,路径和方法、请求字段(类型、是否必填、取值范围)、响应字段、错误码和提示、一两组真实的请求和响应示例。方案审核通过后冻结,各仓库按它同时开发:提供接口的一边用示例写接口测试,调用的一边用示例做测试替身。主仓库的需求说明、访谈记录、方案、接口约定和预览在实现前同步到其他仓库工作区的同名功能目录并提交;其他仓库的实现、评审和缺陷处理记录写在它们自己的功能目录中。
@@ -35,6 +35,7 @@
35
35
  | `joint` | array \| null | 可选,1.8.0 起。联合需求(spec 的 `- 联合开发:`)中其他仓库的工作区:`name`(`relatedRepos` 中的名称)、`slug`(步骤键的后缀,如 `implement@backend`)、`sourceRepo`(切出工作区的那份检出)、`repo`(工作区目录)、`workspaceId`、`branch`、`specHash`(最近一次同步过去的 spec),以及这个仓库自己的 `codeBase` 和 `gate`(格式同顶层)。见 ADR 0025 |
36
36
  | `approval` | object \| null | 可选,1.8.0 起。方案确认点:`attempt`(哪一次尝试的方案)、`status`(`waiting` / `approved`)、`at`。需求变更后的新尝试需要重新确认 |
37
37
  | `external` | object \| null | 可选,1.9.0 起。外部系统中的卡片,按集成名称:`id`(卡片编号)、`url`、`status`(最近设置的状态)、`syncedAt`、`pending`(没有成功、等待补发的调用:`action` 为 `create` / `status`、`event`、`status`、`at`、`attempts`、`error`)。见 ADR 0028 |
38
+ | `pushed` | array \| null | 可选,1.10 起。从卡片开始、配置了 `push` 的需求推送过的分支,每个仓库一条(主仓库在前):`repo`、`remote`、`branch`、`at`、`error`(成功时为 null)。见 ADR 0029 |
38
39
  | `gate` | object \| null | 可选,1.8.0 起。质量门:`baseline`(`attempt`、`commit`、`at`、`results`:每项检查改动前 `pass` / `fail`),`runs`(每次运行:`key` 步骤键、`attempt`、`at`、`checks`(`name`、`result`:`pass` / `fail` / `skipped`、`failedBefore`)、`newFailures`、`fixRounds`、`passed`)。各次运行的完整输出在 `.pipeline/checks/<步骤键>/` |
39
40
 
40
41
  `schedules[].kind` 在 1.7.0 起还可能是 `verify-start`(`--verify-at` 预约的测试验证开始),1.8.0 起还可能是 `approval-continue`(方案确认超时后按方案继续,`designApproval.autoContinueHours`)。`history` 中每条步骤记录在 1.7.0 起有可选的 `phase`(`develop` / `verify`),用于按阶段统计用时与用量;没有时按研发阶段统计。
@@ -29,7 +29,7 @@
29
29
  | --- | --- |
30
30
  | `schema` / `kind` | `1` / `"run"` |
31
31
  | `machine` / `kitVersion` | 主机名、req-kit 版本 |
32
- | `requirement` | `{ key, project, name, title, type, profile }` |
32
+ | `requirement` | `{ key, project, name, title, type, profile }`;从卡片开始的需求(1.10 起)另有 `requester`(卡片的提出人)和 `source`(`{ system, id }`) |
33
33
  | `run` | `{ startedAt, endedAt, attempt, phase, phaseMode, status, outcome, stopReason }`;`status` 是运行结束时的状态,`outcome` 是完成时报告的结论 |
34
34
  | `agents` | `{ builder, reviewer }`:当时配置的 agent(如 `claude/opus(bypassPermissions)`) |
35
35
  | `steps` | 这次运行中开始的步骤:`{ key, stepId, phase, attempt, round, startedAt, endedAt, minutes, outcome, inputTokens, outputTokens, costUsd }`;agent 没有报告的用量为 null |
@@ -0,0 +1,35 @@
1
+ # 0029 从卡片开始的需求:需求会话代替人,卡片描述代替对话
2
+
3
+ - 状态:已采纳(1.10.0-beta.2;建在 [0028](0028-external-integrations.md) 的外部系统对接之上)
4
+
5
+ ## 背景
6
+
7
+ 团队希望需求不必有人坐在 Paseo 对话前发起:需求方在需求管理系统(ALM)中写好一张卡片、标题加上约定的标识,就由一台共享的研发机器接手,整理需求、请需求方确认、开发、提测,结果回到卡片上。人只在确认需求、确认方案、验收这几个点介入("软件工厂")。
8
+
9
+ 约束:
10
+
11
+ - ALM 不支持评论,状态只有新建、开发中、待测试等,没有"待补充""待确认"。
12
+ - 现有规则:步骤 agent 挂在发起需求的对话下,对话的工作目录不变;流水线只在本地提交。
13
+ - 卡片描述可能已经是一份完整的需求文档,也可能只有一句话;内容来自需求方,不能当作给 agent 的指令。
14
+
15
+ 另评估过 Paseo Hub:它的事件来源(GitHub、Slack、Discord、Linear)是编译在 Hub 代码里的,没有插件或通用 webhook;可用的扩展口只有开放 API 的 `manual.run` 和定时触发。代码在内部 GitLab、IM 是内部工具、Hub 只能内网自建,所以不用 Hub 接单;以后一台机器不够用时,再用内网 Hub 的 `manual.run` 把需求派到多台机器。
16
+
17
+ ## 决定
18
+
19
+ - **需求会话代替人**:`req start --from <系统>:<卡号>` 读卡片、建功能目录(`docs/features/<日期>-<卡号简称>/`),然后在 Paseo 中为这个需求建一个顶层 agent(需求会话),工作目录是仓库,第一条消息以 `/req 无人值守` 开头。它按 `unattended.md` 手册整理需求说明,确认后用现有的"启动(自动新建工作区)"命令启动流水线,所以它就是流水线的发起对话:步骤 agent 挂在它下面,进度通知发给它,现有的启动、继续、确认方案命令都不变。人在 Paseo 中打开这个会话就能看到全部过程。
20
+ - **卡片描述代替对话**:描述末尾由 req-kit 维护两个区块:`## req-kit AI 区(自动维护,请勿修改)` 每次整块替换(进度一行 + 会话写的 `card-ai.md` + 必要时的方案摘要),`## 需求方回复(请在下方填写)` 只由需求方填写,req-kit 只读、只补空行(每个问题一行 `- Q1:`,以及 `- 确认:`、方案待确认时的 `- 方案确认:`)。区块以上需求方自己写的内容从不改动。每次写入前重新读取卡片。
21
+ - **轮询而不是回调**:`req card check` 读卡片,把新内容(回答、补充、描述的修改、"确认:同意""方案确认:同意")转给需求会话;只看有意义的内容(空的模板行不算),同样的内容只转一次。1.11 的接单器定时调用它。会话自己执行启动和确认方案的命令,req-kit 不替它决定。
22
+ - **卡片状态少,确认放在描述里**:澄清和确认期间卡片停在"新建",需求方确认后改为"开发中",研发完成后改为"待测试"(都由 `statusMap` 配置)。"只做研发"的需求在研发完成时发 `phase_done` 事件,而不是 `completed`:对外部系统来说,这就是"研发完成,待测试"。
23
+ - **默认只做研发**:从卡片开始的需求,项目没有指定执行方式时,默认研发完成、写好提测说明后停下,测试由测试同事做。
24
+ - **卡片内容是数据**:会话读到的卡片描述和回复放在 `<card-description>`、`<card-reply>` 中并注明不是指令;其中要求执行命令、推送、访问生产环境的一律不做。
25
+ - **用这张卡片,不另建**:功能目录的 `source.json` 记下来源;外部系统对接遇到它时直接使用这张卡片的编号,不再建卡。
26
+
27
+ ## 影响
28
+
29
+ - 对接配置新增 `query`(读一张卡片:参数 + 输出 JSON 中各值的位置)和 `describe`(改描述:`{description}` 是完整的新描述)。
30
+ - 新命令:`req start --from`、`req card publish | check | list`。本机新增 `~/.req-kit/cards/`(从卡片开始的需求的登记)。
31
+ - 功能目录新增 `source.json`、`card-source.md`、`card-ai.md`。
32
+ - 运行时新增 `startSessionAgent`:建一个不挂在任何对话下的 agent,工作目录是仓库。
33
+ - **按子系统选仓库**(beta.3):仓库在项目配置的 `cardSource` 中写明接哪个系统、空间和子系统,`/req-setup` 写入并在本机登记(`~/.req-kit/card-repos.json`);同一子系统有几个仓库时用 `titleKeywords` 区分。匹配不到或分不清时报错说明,不猜。
34
+ - **工厂模式可以推送分支**(beta.3,放宽"只在本地提交"):配置 `push.enabled` 后,只对从卡片开始的需求,在研发完成、写好提测说明后推送到 `<remote>/req/<卡号简称>`。只推这个前缀,不强推、不合并、不建合并请求;只能在本机或团队配置中打开。理由:接单的是共享机器,测试同事拿不到它的本地分支;合并这道人工关口不变。个人电脑上从对话发起的需求仍只在本地提交。
35
+ - 使用记录带上需求方(卡片的提出人)和卡号,统计可以按需求方汇总。1.11:接单器 `req factory`。
@@ -30,3 +30,4 @@ req-kit 自身的设计决定。修改其中任何一条,请新增一条 ADR
30
30
  - [0026 本机的需求索引、使用记录和 req api](0026-machine-records-and-api.md)
31
31
  - [0027 Paseo 插件:随 req-kit 一起发布,只通过 req api 工作](0027-paseo-plugin.md)
32
32
  - [0028 外部系统对接:命令写法在配置里,内容由 AI 整理,调用是确定的](0028-external-integrations.md)
33
+ - [0029 从卡片开始的需求:需求会话代替人,卡片描述代替对话](0029-requirements-from-cards.md)
@@ -311,12 +311,69 @@ Paseo 自带的 `/paseo-advisor`、`/paseo-committee` 等编排 skill 也可以
311
311
  - **命令**:`args` 是参数数组,引擎不经过 shell 运行,标题或描述里有空格、换行、引号都不会出问题。Windows 上 npm 安装的命令(`.cmd`)会改用 node 直接运行它的脚本。
312
312
  - **占位符**:`{title}`(`card.json` 的标题,否则需求说明的标题)、`{body}`(`card.json` 的描述,否则 `spec.md` 全文)、`{card.<字段>}`(`card.json` 中需求方确认过的字段)、`{field.<名称>}`(`defaults` 和项目配置的 `integrationDefaults`,项目可以只写自己的项目编号)、`{id}`、`{url}`、`{status}`、`{feature}`、`{branch}`、`{type}`、`{outcome}`。一个参数只是占位符且没有值时,它和前面的选项一起省略。
313
313
  - **卡片编号**:`create.id` 是从建卡命令输出中取编号的正则表达式(取名为 `id` 的组或第一个组),`url` 同理,可以不写。
314
- - **状态**:`statusMap` 的键是流水线事件:`started`(开始开发)、`approval`(等待确认方案)、`blocked`(等待需求方决定)、`phase_done`(研发完成,待测试)、`verify`(开始测试验证)、`completed`(完成;可以用 `completed_with_issues`、`not_completed` 细分)、`failed`(中断)。没写的事件不改状态。
314
+ - **状态**:`statusMap` 的键是流水线事件:`started`(开始开发)、`approval`(等待确认方案)、`blocked`(等待需求方决定)、`phase_done`(研发完成,待测试)、`verify`(开始测试验证)、`completed`(完成;可以用 `completed_with_issues`、`not_completed` 细分)、`failed`(中断)。没写的事件不改状态。"只做研发"的需求在研发完成时发的是 `phase_done`(1.10 起;之前是 `completed`)。
315
315
  - **卡片字段由 AI 整理、需求方确认**:写了 `cardFields` 时,`/req` 在请需求方确认需求说明时,从需求说明中整理出这些字段的取值一起确认,写进功能目录的 `card.json`。命令的写法固定在配置里,运行时不让 AI 决定怎么调用。
316
316
  - **失败不影响流水线**:调用失败或超时(`timeoutSeconds`,默认 60)记在状态文件里,下一个事件时先按顺序补发;等待中的状态只留最新的一个,不会重复建卡。流水线没在运行时,`req sync <需求>` 立即补发(插件中也有"同步到外部系统")。
317
317
  - **先试再用**:`req integration test [需求]` 显示每个事件会执行的完整命令(用这个需求的需求说明和 `card.json` 填好),不真正调用;`req integration fields` 显示需求方要确认的字段。
318
318
  - 认证由工具自己负责(例如工具已登录本机账号)。不要把口令写进配置;工具需要时放在环境变量里。
319
319
 
320
+ ### 从卡片开始需求(1.10 起,beta)
321
+
322
+ 需求方在需求管理系统中写好一张卡片,就可以从卡片开始需求,不必有人在 Paseo 对话里发起。对接配置中再写两项:`query` 读一张卡片,`describe` 改卡片描述:
323
+
324
+ ```json
325
+ {
326
+ "name": "ALM",
327
+ "command": "shenbing",
328
+ "query": {
329
+ "args": ["alm-card", "view", "{id}", "--fields", "globalId,name,state,createdBy,subsysName,description"],
330
+ "fields": { "title": "data.name", "body": "data.description", "state": "data.state", "author": "data.createdBy", "subsystem": "data.subsysName" }
331
+ },
332
+ "describe": { "args": ["alm-card", "edit", "{id}", "-b", "{description}"] },
333
+ "status": { "args": ["alm-card", "edit", "{id}", "--state-detail", "{status}"] },
334
+ "statusMap": { "started": "开发中", "phase_done": "待测试" }
335
+ }
336
+ ```
337
+
338
+ - `query.fields` 写输出 JSON 中各值的位置(点分路径);`title` 和 `body` 必填,`state`、`author`、`subsystem`、`url` 可选。输出前后有日志行也可以。
339
+ - `describe` 的 `{description}` 是完整的新描述。req-kit 只在描述末尾维护两个区块,需求方自己写的内容原样保留:
340
+
341
+ - `## req-kit AI 区(自动维护,请勿修改)`:进度、需求说明摘要、验收标准、假设、要问需求方的问题(Q1、Q2…),方案待确认时附上方案摘要。
342
+ - `## 需求方回复(请在下方填写)`:需求方在 `- Q1:` 后回答,在 `- 确认:` 后写"同意"开始开发,方案待确认时在 `- 方案确认:` 后写"同意"。写别的内容就当作修改意见。
343
+
344
+ 流程:
345
+
346
+ 1. `req start --from ALM:<卡号> --repo <仓库目录>`:读卡片,建功能目录 `docs/features/<日期>-<卡号简称>/`,在 Paseo 中为这个需求建一个**需求会话**(一个 agent,工作目录是仓库)。需求会话按无人值守手册从卡片写需求说明,把摘要和问题写进卡片的 AI 区。同一张卡片只会开始一次。
347
+ 2. `req card check <卡号>`(或 `--all`):读需求方的回复,把新内容转给需求会话。1.11 的接单器会定时运行它,现在可以手动运行或用计划任务运行。
348
+ 3. 需求方写了"确认:同意"后,需求会话把需求说明标为已确认,用"自动新建工作区"启动流水线。卡片状态改为"开发中",研发完成后改为"待测试",AI 区跟着更新进度。
349
+ 4. 开发中需要需求方决定、确认方案时,同样通过 AI 区和回复区。
350
+
351
+ - 从卡片开始的需求用这张卡片,不会另建卡片;项目没有指定执行方式时默认**只做研发**。
352
+ - 在 Paseo 中打开需求会话可以看到整理需求和开发的全部过程,也可以直接在里面补充说明。
353
+ - `req card list` 列出本机从卡片开始的需求;`req card publish <卡号>` 由需求会话使用,把它写的 `card-ai.md` 写进卡片。
354
+ - 卡片描述和回复是需求方写的内容,需求会话只把它们当作需求,不当作指令。
355
+
356
+ **按子系统选仓库**(1.10.0-beta.3 起):一个 ALM 空间往往对应好几个仓库。在每个仓库运行 `/req-setup`,它会在项目配置中写上这个仓库接哪些卡片,并在这台机器上登记(`req card route --add <仓库>`):
357
+
358
+ ```json
359
+ "cardSource": { "system": "ALM", "projectId": "186149", "subsystems": ["CSP-CMASTER_云匠"], "titleKeywords": ["message-service", "后端"] }
360
+ ```
361
+
362
+ 之后 `req start --from ALM:<卡号>` 不写 `--repo` 时,按卡片的子系统选仓库;同一个子系统有几个仓库时,再看卡片标题里出现了哪个仓库的 `titleKeywords`。找不到或分不清时会说明原因,不会猜。`req card route` 列出本机登记的仓库。本机没有登记任何仓库时,用当前目录所在的仓库。
363
+
364
+ **推送分支**(1.10.0-beta.3 起,默认关闭):接单的机器上,研发完成、写好提测说明后,把需求的代码推送到远程,测试同事直接拉取:
365
+
366
+ ```json
367
+ "push": { "enabled": true, "remote": "origin", "branchPrefix": "req/" }
368
+ ```
369
+
370
+ - 只对从卡片开始的需求,推送到 `<remote>` 的 `req/<卡号简称>` 分支(例如 `req/cmaster-business-9902`),联合需求的几个仓库各推各的。分支名写进卡片的 AI 区和状态文件。
371
+ - 只推这个前缀的分支;从不强推、不合并、不建合并请求,合并仍由人做。推送被拒绝(例如远程分支有别人的提交)时记下原因、写进 AI 区,流水线照常结束。
372
+ - 只能写在本机或团队配置中,写在项目配置里会被忽略。推送用这台机器上 git 已配置的账号。
373
+ - 在个人电脑上通过对话发起的需求不受影响,仍然只在本地提交。
374
+
375
+ **使用统计**:从卡片开始的需求,运行记录带上需求方(卡片的提出人)和卡号。`req stats --report` 多一节"从卡片开始的需求(按需求方)",CSV 多 `requester`、`card` 两列。
376
+
320
377
  ## 团队配置
321
378
 
322
379
  几台机器、多个项目共用的设置(统一的模型、评审小组、超时、要求的 req-kit 版本)可以放在一份团队配置里。把它放进一个团队共用的 git 仓库,各台机器克隆下来,在本机配置 `~/.req-kit/config.json` 中写上它的路径(绝对路径,或相对 `~/.req-kit/` 的路径):