ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Cindy 开发工作流实战:worktree 会话契约、DCO 门禁与 PR Review 口径

Cindy 开发工作流实战:worktree 会话契约、DCO 门禁与 PR Review 口径
  • 人工智能
  • AI Agent
  • 代码智能体
  • 大模型
  • AI 技能
  • Agent 记忆
  • 工具调用
  • MCP Clients

【免费下载链接】cindy

Consider it done. The open-source AI agent that works out of the box · 想到,就能做到。开源、开箱即用的 AI Agent。

项目地址:https://gitcode.com/GitHub_Trending/cind/cindy
点击查看免费下载

本文以 Cindy 客户端仓的权威开发规则 docs/dev-rules/development-workflow.md 为主线,系统拆解在 Cindy 内嵌 worktree 会话中工作、提交 PR、直推main以及做 code review 时必须遵守的硬性约束。读完后你将能准确判断:哪些改动必须走 PR、DCO 签名如何一次配对通过、test:unit:related到底会选哪些用例、worktree 目录不可用时任务如何继续,以及 P0/P1/P2 的严重度边界在哪里。

文档定位:它细化的是根 AGENTS.md 的哪两节

development-workflow.md 的状态被标注为「权威开发规则(authoritative)」,读取时机是三个场景:在 Cindy 内嵌的 worktree 会话里工作、准备提交或直推、做 code review 之前。

它不重复根 AGENTS.md 的通用流程,而是细化其中「通用工作流程」与「Git 与交付」两节,补齐三块内容:worktree 会话契约、直推main的额外门禁、review 严重度口径。根文件只保留所有任务都适用的规则、风险入口与文档索引,专题规则统一放在docs/dev-rules/,这是仓库的规则组织约定。

因此阅读顺序应当是:先读 AGENTS.md 拿到模块入口与绝对安全底线,再按触发条件读本文件。本文件中的每一条都不是建议,而是会以脚本、hook 或 CI check 形式落地的约束。

1. Dogfooding:在托管 worktree 会话里工作

1.1 先确认 checkout 完成,再装依赖

Cindy 托管的会话级 git worktree 位于<baseRepo>/.cindy-worktrees/<name>,品牌迁移前的历史目录是.xdt-worktrees/<name>。这两个目录名在共享包中被定义为常量,见 worktreePaths.ts:

/** Cindy 新建托管 worktree 使用的目录名。 */ export const MANAGED_WORKTREE_DIR_NAME = '.cindy-worktrees'; /** 品牌迁移前使用的目录名;只用于识别和恢复既有 worktree。 */ export const LEGACY_MANAGED_WORKTREE_DIR_NAME = '.xdt-worktrees';

规则要求:worktree 创建返回时,后台的完整 checkout 可能仍在进行。跑任何pnpm命令前必须先确认package.json存在且git status干净,否则你会在一个半成品目录里 install,得到难以复现的依赖错误。

关键差异是:worktree 与 baseRepo共享.git,但不共享node_modules。所以首次进入新 worktree 必须pnpm install,耗时可能数分钟,需要给命令留足超时时间。

# 在 worktree 会话中的自检顺序 ls package.json && git status --short # 确认 checkout 完成且工作区干净 pnpm install # 首次进入新 worktree 必做,可能数分钟

1.2 「改了没反应」不是 bug

Vite HMR 只 watch 启动 dev 实例的那份 checkout。worktree 下的改动既不热更,也不随重启生效。这条规则的价值在于排障方向:如果你在 worktree 里改了渲染层代码却看不到变化,第一反应不应该是怀疑代码逻辑。

正确做法是分层验证:

目的在 worktree 内的做法
类型正确性pnpm --filter desktop typecheck
定向行为验证定向vitest run(具体文件或包)
运行时验证pnpm restart:desktop:remote -- --isolated=@worktree
提交前门禁必须回到第 2 节的提交前验证

--isolated=@worktree会按 checkout 目录名派生独立 userData 沙箱,不会停掉宿主实例,也不会与其他 checkout 抢默认dev沙箱。启动成功的判据是命令行出现DESKTOP_DEV_VERDICT=ready;看到failed或根本没有 verdict 行,都不能声称开发版已起来。沙箱、verdict 与 userData 冲突门的完整细则见 desktop-development.md。

pnpm restart:desktop:remote -- --isolated=@worktree # 等待并确认最后一行 verdict # DESKTOP_DEV_VERDICT=ready

1.3 日志不在你的 cwd 下

dev 日志写在启动 checkout(通常是 baseRepo)的apps/desktop/logs/。在 worktree 里tail -f logs/...大概率什么都读不到——这不是日志失效,而是路径归属问题。读日志时要拼 baseRepo 的绝对路径。

1.4 会话结束不等于必须提交

会话是否 commit 由用户或宿主工作流决定,不能仅因会话结束就强制提交。会话被删除或归档时,脏 worktree 的处理是:先把改动和新文件存进 Git 快照,再删目录;被.gitignore忽略的文件(依赖、构建产物)和 worktree 内克隆/初始化的嵌套仓库不保留。

一个高频误解被明确纠正:PR merged/closed 不等于 Cindy 会话已结束。只要 owning session 仍 active,任何外部 Git cleanup 都必须跳过对应的.cindy-worktrees/.xdt-worktrees目录,以及本地cindy/*/xdt/*分支,交给用户显式归档/删除会话时回收。禁止手动git worktree remove,否则会让 active session 的 cwd 悬空。

手动干活需要豁免自动回收时,放.worktree-keep哨兵文件即可。该哨兵是代码里的常量,见 safety.ts:

export const WORKTREE_KEEP_SENTINEL = '.worktree-keep'; /** worktree 根目录存在 `.worktree-keep` 哨兵 ⇒ 一切自动回收跳过。IO 失败按无哨兵处理。 */

它在回收链路的多处生效:WorktreeManager.ts 在 dirty/stash 判定之前无条件保留,WorktreePool.ts 与 managedRecycle.ts 同样先查哨兵。

1.5 stale prebundle 白屏

给带依赖的内部包新增 export 后,运行中实例可能因 stale Vite prebundle 报does not provide an export named X并白屏。处理方式是让受影响实例完整重启(re-optimize),而不是改代码。这条被单独写进规则,是因为它极易被误诊为自己的实现错误。

2. 托管 worktree 不可用时的任务连续性

这是文档中最容易被跳读、但实现最复杂的一节。它规定了当本机任务发送前发现托管 worktree 无法恢复时的降级顺序。

2.1 恢复优先级

  1. 优先按原分支和快照恢复托管 worktree。
  2. 仅在确认目录缺失、且成功枚举 Git 引用后确认原分支不存在时,才使用当前 owner 的托管对话目录继续运行。
  3. 使用备用目录时,保留数据库里的项目工作目录和 worktree 绑定;备用目录按任务 ID 与原工作目录的哈希定位。
  4. 重启后重新优先恢复原 worktree;仍失败则复用同一备用目录,不搬运或删除其中的文件。
  5. DB / Git 临时错误、绑定不匹配与快照冲突:保留原目录重试,不登记备用目录。
  6. 同一运行期不自动切回。明确换到另一工作目录时,不复用旧绑定的备用目录。
  7. 原地重建普通目录的现有行为保持不变;不把失败的 Git worktree 建成空目录,也不自动切到项目根继续改代码。

2.2 源码印证:fallback 目录的哈希身份

实现位于 workingDirectoryRecovery.ts。备用目录名由sessionId与原工作目录的绝对路径共同决定,见该文件 L17-L28:

export function worktreeConversationFallbackDir(dialoguesRoot, sessionId, workingDir) { return path.join(dialoguesRoot, 'worktree-recovery', recoveryDirectoryKey(sessionId, workingDir)); } export function dialogueConversationFallbackDir(dialoguesRoot, sessionId, workingDir) { return path.join(dialoguesRoot, 'dialogue-recovery', recoveryDirectoryKey(sessionId, workingDir)); } function recoveryDirectoryKey(sessionId, workingDir) { return createHash('sha256').update(JSON.stringify([sessionId, path.resolve(workingDir)])).digest('hex'); }

这正好解释了规则里「按任务 ID 与原工作目录的哈希定位」和「明确换到另一工作目录时不复用旧绑定的备用目录」:哈希把 session 与原始路径绑成一个不可拆分的身份。

2.3 两种恢复模式

recover()的mode参数只有两个取值,语义差别很大:

  • 'ordinary':普通目录恢复。若目录不存在(ENOENT),会重建目录并生成说明;只有文件系统不可用时才切 fallback。
  • 'unrestored-worktree':Git 恢复已失败。此时绝不再把原路径当作普通目录去 probe/mkdir,而是直接走 fallback。代码注释写得很直白:an empty folder is not a restored worktree。

不可用文件系统的判定是一组明确的 errno 白名单,见 L9-L12:

['EIO', 'ENOTCONN', 'ENODEV', 'ESTALE', 'ETIMEDOUT', 'EHOSTUNREACH', 'ENETUNREACH', 'WORKDIR_PROBE_TIMEOUT']

除了 errno,mountUnavailable()还覆盖了几类「看起来存在、其实不可用」的情形:requiredRoot探测失败、macOS 上/Volumes/X只是挂在父文件系统上的裸挂载点(通过比较dev与 realpath 识别,避免把/Volumes/Macintosh HD -> /这类别名误判)、以及向上遍历祖先时dev发生变化(device-changed)。

2.4 恢复说明如何进入模型上下文

恢复不是静默发生的。recover()会在pending里登记一段带[Working directory recovery]前缀的 note,文案随模式不同而不同;unrestored-worktree的版本明确写出「原代码、分支与未提交改动未被恢复或复制」「不要在原路径建空替代目录」「不要当作原 worktree 继续编辑」。

随后 makerSendTransaction.ts 通过peekWorkingDirectoryRecoveryNote/consumeWorkingDirectoryRecoveryNote消费它,让说明随本轮消息传给 Agent。文档中的「消息被接受之后才消费说明」对应consume的语义:dispatch 跨过不可逆边界(accepted)后才清除,未被接受或抛错时保留 pending,下一轮继续提示。

另有两条边界:SSH 不使用本机备用目录;设备互联和手机沿用被控 Desktop 的发送链。回归覆盖见 workingDirectoryRecovery.test.ts 与 makerSendTransaction.test.ts。

3. 提 PR 与直推main:默认 PR-first

仓库默认PR-first:代码和文档通常从非默认分支通过 PR 进入main。直推main只由具备 bypass 权限的维护者明确选择,并且要额外执行第 5 节的门禁。

3.1 PR 正文就是 reviewer 的第一道过滤

PR 的 Title/Description 以 .github/PULL_REQUEST_TEMPLATE.md 为准。模板要求的三段核心结构是:这次改了什么/怎么验证的/风险。

标题格式在模板开头就固定了:

<type>(<scope>): <简短描述>(scope 可省略) type:feat / fix / refactor / perf / chore / docs / test / revert / build / ci

模板还要求必须说明的几类内容:

  • 涉及 SQLite migration、system prompt、协议、原生层或跨平台差异时,必须在「风险」里说清影响与回滚/降级方式。
  • 涉及 UI 时必须在「UI 变化」注明引用的设计规范章节与约束,正本为 docs/design-rules/DESIGN.md。
  • 涉及「存量插件兼容」时必须写「存量插件影响:无」或「有 + 迁移与提示方案」。
  • 会改变 mobile runtime fingerprint(触发冷更)时要说明为何不可避免、存量装机影响范围与发版节奏建议。
  • 新增或改写测试时,按engineering-conventions.md§3.2 补充「测试价值」各项,含单独运行该文件的实测耗时。

一条常被忽视的判定口径:Reviewer 只看 Title + Description 决定要不要 review,写不清直接退回。

3.2pr-design-basis的轻校验到底校什么

CI 的pr-design-basis会在 PR 变更命中 UI 路径时轻校验「引用的设计规范」字段。判定逻辑在 scripts/check-pr-design-basis.mjs,几个关键实现细节值得作者提前知道,否则会反复撞同一个红:

UI 路径是前缀白名单,不是全仓扫描(L20-L31):

const UI_PATH_PREFIXES = [ 'apps/desktop/src/renderer/', 'apps/mobile/app/', 'apps/mobile/src/auth/', 'apps/mobile/src/components/', 'apps/mobile/src/i18n/', 'apps/mobile/src/notifications/', 'apps/mobile/src/session/', 'apps/mobile/src/settings/', 'apps/mobile/src/theme/', ]; const UI_FILE_SUFFIXES = ['.css', '.scss', '.less'];

只有命中这些前缀或后缀的变更才算「涉及 UI」。改apps/desktop/src/main/或packages/不会触发本检查。

字段提取会先剥 HTML 注释(L56-L73)。模板自带的填写说明里含有DESIGN.md等字样,若不剥掉会造成假通过。提取范围是从「引用的设计规范」标签行到下一个 Markdown 标题为止。

任务清单行不算字段锚点(L46):

const CHECKLIST_LINE_PATTERN = /^\s*[-*+]\s*\[[ xX]\]/;

因为模板「提交前检查」里的勾选项文案同时含有字段标签和「不涉及」,被当成字段内容就会假通过。

「不涉及」豁免必须带理由,去掉「不涉及」和标点后至少剩 4 个字符(MIN_EXEMPT_REASON_CHARS = 4),所以「不涉及:纯逻辑重构,无视觉/交互/文案变化」可以过,空写「不涉及」不行。

已删除的设计文档会被剔除后再判断:figma-component-spec的路径/文件名会先被REMOVED_DESIGN_DOC_PATTERN替换成空格,避免docs/design-rules/figma-component-spec.md §4靠目录前缀蒙混过关。

注意规则原文的提醒:通过 CI 不代表内容合格,质量仍由 review 把关。本地可离线调试:

node scripts/check-pr-design-basis.mjs --body pr-body.md --files changed-files.txt

4. DCO 签名:硬性门禁的实现细节

这是全仓最容易踩、也最容易修错的一条。

4.1 要求本身

每个 commit 都必须带Signed-off-bytrailer,且其中的名字与邮箱都要与 commit 的 author(或 committer)一致。生成方式:

git commit -s # 单次提交签名 pnpm dco:install-hook # 一次安装 hook,后续提交自动补签 pnpm check:dco # 提交前本地自查

一个常见误区被文档点名:git commit本身没有自动签名的配置项,format.signOff只作用于git format-patch/git am。所以要么每次-s,要么装 hook。

4.2 权威门禁与本地自查的关系

  • PR 上的权威门禁是DCO GitHub App的 check:它校验该 PR 的每个 commit,豁免 merge 与 bot,不追溯历史。
  • 本地pnpm check:dco是自查,判定刻意对齐 App 或更严,目标是「本地通过 ⇒ App 必过」。

.github/dco.yml 开启了 remediation commit:

allowRemediationCommits: individual: true thirdParty: true

这意味着漏签可以不改写历史:推一个后续 commit 用固定格式为先前的 commit 补上签名,避免已有 review 评论全部 outdated。格式见 CONTRIBUTING.md 的 DCO 一节。

但本地脚本不识别remediation commit,这是刻意取舍——因此本地可能红、PR 可以绿,反之不成立。

4.3 本地脚本的三处「刻意更严」

scripts/check-dco.mjs 的注释把设计动机讲得非常清楚:放宽会造成「本地绿、PR 红」,那才是最坏方向。三处不放宽:

其一,签名行正则与 DCO App 逐字对齐(L38):

const SIGN_OFF_LINE = /^Signed-off-by: (.*) <(.*)>\s*$/i;

对应三条禁令:不允许行首空白(App 的^锚在行首,缩进过的行在它眼里根本不是签名);Signed-off-by:后只允许一个空格(写两个空格时 App 会把多出来的空格算进 name);捕获值不 trim(App 拿原样值比较,Alice不等于Alice)。

其二,name 与 email 成对比较,而不是拆成两个集合(L157-L169)。App 是把 name 与 email 拆成两个集合分别判断,于是author=Alice<a@x>、committer=Bob<b@x>时Alice <b@x>也能过——尽管这个身份并不存在。本地脚本要求整体匹配某一个真实身份。

其三,邮箱形状校验偏严(looksLikeEmail,L88-L100)。local part 限定 RFC 5322 的 atext 字符集,域名 label 不能以连字符开头结尾、不允许下划线、必须有字母 TLD(于是 git 未配user.email时自动生成的user@hostname会被拒),并施加 254 / 64 / 63 三层长度上限。

4.4 豁免与范围

exemptReason只豁免merge commit(父提交数量大于 1),因为只有它能离线可靠判定。bot 豁免交给 App 按 GitHub 账号类型判断——离线拿不到也伪造不了,而邮箱谁都能写成999999+not-a-real-account[bot]@users.noreply.github.com。所以本地照常报 bot 提交,只在输出里说明「若它真是 bot,PR 上的 App 会豁免」。

默认基准的顺序也值得记住(L55):

const DEFAULT_BASE_CANDIDATES = ['upstream/main', 'origin/main', 'main'];

upstream/main排最前:从 fork 干活时origin/main可能领先于上游,拿它当基准会把 fork 自己那些未签名的提交排除在范围外,而 PR 的真实 base 是上游。范围本身用merge-base..head而不是base..head,避免 base 分支在 PR 开着期间前进、把他人提交算进来造成误报。

4.5 hook 为何用 committer 身份

.githooks/prepare-commit-msg 有一个关键设计:

# Use the COMMITTER ident, exactly like `git commit -s` does. IDENT=$(git var GIT_COMMITTER_IDENT) || exit 0 SIGNOFF=$(printf '%s\n' "$IDENT" | sed -n 's/^\(.*>\).*$/\1/p')

签名是「执行提交的人」的声明。若用 author 身份生成,在git commit --author=...、cherry-pick 或 rebase 别人的 patch 时就会替他人伪造 DCO 认证。检查同时接受 author 或 committer,所以用 committer 身份仍能通过。

hook 还处理了三个边界:merge commit 直接exit 0(DCO 豁免,不该签);已存在同一签名则不改动(支持--amend二次执行);交互式提交时 message 只有注释,需要构造git commit -s使用的布局(空 subject 行、空行、签名),而不是让interpret-trailers把签名塞到第 2 行。最后一处细节是显式传--if-exists addIfDifferent --if-missing add,因为默认值来自trailer.ifExists/trailer.ifMissing,开发者若设成doNothing会静默产生未签名提交。

4.6 漏签怎么修

# 只有最新一个 commit 漏签 git commit --amend -s --no-edit # 多个 commit 漏签 git rebase --signoff <base> # 更新 PR git push --force-with-lease

另外一条排障提示:自动 code review 沙箱 checkout 出的 HEAD 可能是平台合成的瞬时 commit(不存在于本仓库,GitHub 上查不到该 SHA)。对这类合成 SHA 跑check:dco的失败结果不构成缺签证据。判定 DCO 是否通过,一律以 PR 上的 DCO App check 与真实提交范围(origin/main..PR head)为准。

5. 提交前验证:范围、并发与排队

5.1 验证目标与执行方式分开

规则把两件事明确拆开:验证目标由改动影响面决定;本机执行方式(资源预算、并发、执行时机、是否跨任务排队)由用户或宿主决定。仓库默认值不能覆盖这些选择,也不授权启动额外测试进程、终止其它任务,或把一次机器过载经验升级为所有贡献者的固定限制。

5.2 基本动作

pnpm test:unit:related # 默认选测 pnpm --filter <包名> run --if-present typecheck # 每个涉及 package pnpm check:dev-docs # 文档改动

脚本定义见 package.json:

"test:unit:related": "node scripts/test-workspaces.mjs --tier unit --related", "test:all": "pnpm test:runner && node scripts/test-workspaces.mjs --all", "check:dev-docs": "node --test scripts/__tests__/dev-docs-contract.test.mjs"

已经完成等效的定向测试与类型检查时,无须为每次 commit 再跑一遍整仓。文档改动运行适用检查即可,不要求无关业务单测。

5.3test:unit:related怎么选

规则给出了完整的选测语义,实现见 scripts/test-related.mjs 与 scripts/test-workspaces.mjs:

  • 基准分支优先级:优先upstream默认分支(含upstream/main/upstream/master),其次origin默认分支,最后才回退本地main/master。避免落后的个人 fork 扩大测试范围;运行前应先更新目标分支引用。代码中对应GIT_BASE_REFS数组。
  • 文件来源:包含已提交、已暂存、未暂存和未跟踪文件。
  • 选测粒度:同一包源码通过 Vitestrelated选测;公共包源码变化时,依赖方跑整包单测(buildDependentMap依据workspace:依赖关系推导)。
  • 升级为整包的触发条件:包内package.json、Vitest 配置或删除文件时,对所属包及受影响依赖方跑整包。
  • 不跳过的文本产物:i18n/GLOSSARY.md与docs/legal/notices/是有内容断言的生成产物,仍运行根级 runner 验证,不能仅因扩展名是 Markdown/文本而跳过。这一条在shouldRunTestRunner()里有显式分支。
  • 保守回退:测试调度脚本、根依赖清单/锁文件、workspace 配置、根 Vitest 配置,或无法确定 Git 基准时,仍保守选择完整单测。WIDE_ROOT_FILES集合即为此而设。
  • 普通 workflow 变化只触发根级 runner 校验。

5.4 并发默认值与调低方式

文档给出的默认值:

  • workspace runner 默认最多并行min(4, os.availableParallelism())个普通 workspace;
  • 每个普通 Vitest workspace 使用 1 个 worker;
  • Mobile 使用 4 个 worker;
  • Desktop 最多 8 个且随可用 CPU 下调;
  • 重型 workspace 在本次 runner 内独占;这些边界不限制其它 session。

前两条在代码中可验证,见 test-workspaces.mjs:

const MAX_DEFAULT_WORKSPACE_CONCURRENCY = 4;
return Math.max(1, Math.min(MAX_DEFAULT_WORKSPACE_CONCURRENCY, available));

调低整体 workspace 并发:

pnpm test:unit:related -- --workspace-concurrency=1

需要不同的 worker 配额时,直接调用目标包 Vitest 的--maxWorkers。--workspace-concurrency与--lock/--no-lock的解析见 test-workspaces.mjs,其中--lock与--no-lock同时传入会直接报错。

5.5 跨 worktree 排队:默认关闭

这是容易被误解的一条:只有主动传--lock的本地重型测试命令才参与同仓共享的 loopback TCP 锁。--no-lock仅保留兼容。实现见 scripts/test-gate-lock.mjs:

  • 锁地址为127.0.0.1,端口范围从 49152 起、共 16000 个,逐个候选探测;
  • 只对unit/db/git-integration/integration/e2e这些重型 tier 生效(HEAVY_TEST_TIERS);
  • CI 环境自动跳过(isTestGateCiEnvironment);
  • 等待超过 15 分钟以退出码 75结束,表示测试尚未执行——不是失败;
  • 直接运行 Desktop Vitest 不再隐式加第二层锁。

锁只协调同样选择--lock的进程,不能管理未选择排队的任务。有意统一预算时由使用者或宿主协调各入口。

5.6 长测试与如实记录

耗时不确定的检查优先后台运行并保留进度。工具结束等待不等于测试失败,不因等待时间较长重复启动或终止仍在正常运行的测试;外层超时按选定范围和本机情况设置。

如实记录是硬要求:本次改动导致的失败须修复;既有或环境故障要说明证据、影响和未完成项;不伪造通过、不删除或放宽有效断言。需要保存未完成工作时可作 WIP commit。完整测试与远端必需检查仍由 CI 和合并规则保障,本地定向验证不能冒充完整 CI 通过。PR「怎么验证的」一节没跑不许写已跑。

6. 直推main的额外门禁

直推是例外路径,因此门禁更重:

  1. push 前由独立 reviewer 对最终 diff 做一次对抗性 review,对照docs/下规则找实际问题;
  2. 发现P0/P1 必须先修复并重新 review,直到没有 P0/P1;
  3. commit 可以先创建,但push 的必须是 review 通过的最终 commit。

注意「独立 reviewer」与「最终 diff」两个限定词:自审自己刚写的 commit、或 review 了中间态再继续改,都不满足要求。

7. Review 严重度口径

对照docs/下各规则与 .github/PULL_REQUEST_TEMPLATE.md(以现行内容为准,不凭记忆):

级别定义处置
P0红线/崩溃/数据丢失/跨平台失效/安全不改不能合
P1明显 bug/规范违反/影响面没处理干净本次必须修,但不阻断流程
P2可选优化 / 风格偏好不报

两条配套要求:

核对受影响的文档。改动改变已有行为时,结合实现和测试核对对应权威文档中的旧结论;发现冲突就在本次改动中修正,并在相关说明旁链接实现或测试,便于后续核对。不涉及文档变化的 PR 无需修改文档,也无需另写经验总结。

经验回写到已有依据。纠正和排障发现说明错误或不完整时修原文;说明正确但入口遗漏时补入口或触发条件;能自动验证的问题优先补回归测试。一次环境故障不默认升级为长期规则——这条与第 5.1 节「验证目标与本机执行方式分开」是同一取向。

8. 速查清单

在 worktree 会话里开工:

ls package.json && git status --short # checkout 完成、工作区干净 pnpm install # worktree 不共享 node_modules pnpm --filter desktop typecheck # 增量验证 pnpm restart:desktop:remote -- --isolated=@worktree # 需要运行时验证

提交前:

pnpm check:dco # Signed-off-by 自查 pnpm test:unit:related # 与影响面匹配的选测 pnpm --filter <包名> run --if-present typecheck pnpm check:dev-docs # 仅文档改动时

关键判据与阈值:

项值来源
托管 worktree 目录.cindy-worktrees/ 历史.xdt-worktreesworktreePaths.ts
手动保留哨兵.worktree-keepsafety.ts
独立 dev 沙箱--isolated=@worktreedesktop-development.md
启动成功判据DESKTOP_DEV_VERDICT=readyrestart-desktop-remote.mjs
DCO 默认基准upstream/main→origin/main→maincheck-dco.mjs
DCO 本地豁免仅 merge commitcheck-dco.mjs
设计依据豁免最小理由长度4 字符check-pr-design-basis.mjs
workspace 默认并发上限min(4, os.availableParallelism())test-workspaces.mjs
测试排队超时退出码75(15 分钟)test-gate-lock.mjs

把这套规则当作流水线来理解会更顺手:worktree 契约保护正在运行的开发实例与用户数据,DCO 与 PR 模板保证贡献可追溯,test:unit:related把验证成本控制在影响面内,review 严重度口径则决定一个 PR 能不能合、以及什么时候必须停下来修 P0/P1。任何一环被跳过,都不会立刻报错,但会在 review 或 CI 上以更贵的方式回来。

  • 人工智能
  • AI Agent
  • 代码智能体
  • 大模型
  • AI 技能
  • Agent 记忆
  • 工具调用
  • MCP Clients

【免费下载链接】cindy

Consider it done. The open-source AI agent that works out of the box · 想到,就能做到。开源、开箱即用的 AI Agent。

项目地址:https://gitcode.com/GitHub_Trending/cind/cindy
点击查看免费下载

相关推荐

上一篇:多终端无缝协作:z命令的会话同步方案
下一篇:VietOCR Transformer OCR:10分钟从零开始部署越南文字识别终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进