本文面向为个人或团队设计、搭建 AI 辅助编程工作流的工程师。
文中的参考实现,取自开源项目 Tack Harness ,可按需裁剪。完整源码可见:Github
1. 设计前的评估
1.1 一个基本判断
Claude Code、Cursor、TRAE、Codex 等编程 Agent,对大模型提供了一定的约束,但目前仍然不能代替编程领域的 Harness 工程。自己专属的编程工作流,不仅可以沉淀专属知识和个人编程偏好,还可以对大模型提供更清晰可见的引导。Harness 直接决定了模型"能看到什么、能做什么、做错了能不能被发现"。在模型能力趋同的前提下,Harness 的设计质量往往是系统可靠性的决定性因素。
Harness 须同时回答五件事:在每个决策点让模型看到什么(上下文)、允许模型做什么动作(工具)、哪些动作默认禁止(约束)、做完之后怎么判断对错(验证)、发现错误后如何恢复(纠正)。不仅要让系统能干活,还得约束系统按照预期干活。
可以借鉴 Tack Harness 的设计原则:流程可固定(凡可脚本完成的不依赖大模型)、能力可扩展(新增一个 Markdown 文件即注册一条能力)、状态可追踪(status.yaml 为唯一有状态文件)、改动可隔离(worktree 隔离各需求)、经验可沉淀(任务结束自动把实践固化为命令或规则)。
1.2 三项边界
动手搭目录之前,须先明确以下三项边界:
- 首要问题:当前最需解决的痛点是什么。常见的问题是:跨会话项目上下文缺失、研发流程不一致、历史经验无法复用等。
- 决策权限划分:须明确哪些操作由模型自动执行,哪些必须人工干预。典型人工节点包括:分支合并、版本发布、任务目录删除、向公共知识库写入内容。
- 使用范围:工作流仅服务于个人,还是服务于团队。前者允许快速迭代,后者须具备可升级、可评审、可交接的特性。
1.3 复杂度控制
从最简单的方案起步,只在确实必要时才增加抽象。每多一层间接,都是日后调试时的盲区。如果提示词加几句就能解决问题,不要为此引入新脚本;如果流程在两个任务中重复出现了三次以上,才考虑固化为命令。
实施应遵循最小可用原则:先解决首要痛点,经两周实际使用后再扩展模块。不建议在未验证任何痛点的情况下一次性固化完整研发流程。
2. 目录骨架
工作流的物理结构由五个职责目录与一份常驻说明书组成。以下为 Tack Harness 实际采用的目录布局:
my-project/
├── AGENTS.md # 常驻说明书:命令路由 + 核心约束 + 数据来源
├── tack.yaml # 空间登记:版本、项目(关键词/仓库映射)、工作区列表
├── harness/ # 开发过程定义(需求无关,可自定义,升级三方比较)
│ ├── README.md # harness 的使用说明
│ ├── cmd/ # 命令:发现、路由、准入准出
│ ├── agents/ # 可委派角色:独立上下文并行执行(explorer/architect/reviewer)
│ ├── workflow/ # 工作流:状态机与命令编排
│ ├── script/ # 固定流程脚本(Windows 统一经 run.ps1 启动器调用)
│ │ └── hook/ # IDE Hook 可选加速层(默认不启用、不拦截)
│ ├── rule/ # 业务、代码与安全规则(不参与路由,按需加载)
│ ├── template/ # 命令、工作流、文档、工作区模板
│ └── reference/ # 通用方法论与复杂独立能力(随 harness 分发,不接受项目沉淀)
├── wiki/ # 公共知识:按项目隔离的项目 wiki
│ └── <project>/ # 项目 wiki(索引 + 小文件)
├── space/ # 工作空间:每个工作一个目录(<YYYYMMDD>-<分支名>)
├── repo/ # 代码主仓库:只保留一份,只读基准
└── .tack/ # 框架本地运行时数据(gitignore,不入库、可随时清理)
├── log/ # 日志
├── backup/ # 回滚备份
├── tmp/ # 临时文件
└── state/ # 本机状态
各目录的职责与禁放内容如表 2-1 所示。
表 2-1 目录职责划分
| 目录 | 职责 | 禁止内容 |
|---|---|---|
AGENTS.md |
路由入口、全局硬性约束、数据位置指引 | 项目列表、工作区列表等结构化登记 |
tack.yaml |
结构化登记:版本、项目名、关键词、仓库映射、工作区列表 | 自由散文式描述 |
harness/cmd/ |
与业务无关的命令手册 | 业务知识、代码、任务进度 |
harness/workflow/ |
状态机定义与命令编排 | 具体命令的执行细节 |
harness/agents/ |
可委派角色定义(独立上下文并行执行) | 参与命令路由 |
harness/script/ |
确定性机械操作(Git 批量操作、状态回写、路由扫描) | 需语义判断的逻辑 |
harness/rule/ |
编码规范、安全边界、读写纪律 | 任务特定内容 |
harness/template/ |
命令、工作流、文档模板 | 具体命令的正文 |
harness/reference/ |
通用方法论与复杂独立能力 | 项目特定沉淀(升级会覆盖) |
wiki/<project>/ |
跨任务稳定知识 | 易变代码逻辑、单次任务细节 |
space/ |
单次任务的过程产物与状态 | 跨任务须保留的知识 |
repo/ |
代码只读基准 | 直接的代码修改 |
.tack/ |
框架运行时数据 | 任何手工编辑 |
2.1 Git 双层边界
空间根目录(AGENTS.md、harness/、wiki/、space/ 工作文档)与业务代码仓库分离为两套 Git 仓库。空间根仓库的提交由框架在各命令阶段自动完成,用户无需操作;用户只在 space/<YYYYMMDD>-<分支名>/repo/ 工作区代码仓库内执行提交、推送等 Git 操作。此边界使工作流本身的演进历史与业务代码历史互不干扰。
3. 常驻说明书 AGENTS.md
该文件是模型每次会话加载的第一份文档,须严格控制篇幅。上下文窗口是稀缺资源,每多塞一行不常用的信息,都在为每次会话支付 token 成本。常驻层只保留三类内容:命令路由方式、全局硬性约束、数据位置指引。参考结构如下:
markdown
# 项目常驻说明书
## 命令路由
收到用户请求后,执行 `harness/script/scan-routes.sh resolve "<输入>"`:
- 唯一命中:读取对应命令文件并按其执行
- 多命中:列出候选,等待用户选择
- 无命中:直接响应用户,必要时建议新建命令
## 全局约束
- 代码修改仅限 space/<当前工作区>/repo/ 内,禁止直接修改 repo/
- 禁止 git push --force、git commit --no-verify、git reset --hard
- 任务进度统一写入 space/<工作区>/status.yaml,不在对话中凭记忆判断
- 写入 wiki 前须先读现有索引,有同主题文件则就地融合,不新建碎片
## 数据位置
- 工作区:space/<YYYYMMDD>-<分支名>/
- 项目知识:wiki/<项目名>/
- 命令手册:harness/cmd/
- 状态查询:harness/script/work-status.sh
项目名、服务与仓库映射、工作区列表等结构化数据应存放于 tack.yaml,由 harness/script/project.sh 按需读取。判断标准很简单:一条信息是否在每次会话的每个决策点都需要?是则放常驻层,否则放按需加载层。
4. 记忆系统的三层结构
4.1 为什么需要分层
把所有信息塞进一份说明文件,会面临三个问题:上下文成本随项目规模线性膨胀;模型在长文本中难以定位关键约束;不同生命周期的信息被混在一起------临时状态被当成长期规则,长期知识被当成一次性细节。
合理的做法是按生命周期划分三层,每层的信息形态、读写频率与加载方式都不同。
4.2 第一层:会话轨迹
单次会话内产生的用户输入、模型回复与工具调用结果构成运行轨迹,随会话结束而丢弃。这一层不需要持久化,由模型的上下文窗口自然承载。本工作流不对其做额外设计。
4.3 第二层:工作区短期记忆
每个任务对应独立目录 space/<YYYYMMDD>-<分支名>/,记录该任务的过程状态。初始仅创建两份文件:
status.yaml:唯一有状态文件,记录当前阶段、进行中任务与后续步骤;context.md:原始需求(可多条/分批追加)、参考链接、约束条件。
其余目录(story/、doc/、run/、repo/)在首次产生文件或检出 worktree 时按需创建,不预建空目录。这一层对应"任务级业务状态":它告诉模型"当前在哪、下一步做什么",使任务中断后恢复会话时不必从零开始。
status.yaml 推荐字段如表 4-1 所示。选择结构化字段而非自由文本,是因为这层数据需要被脚本原子读写------任务领取、状态迁移、进度汇总均由脚本完成,字段必须稳定可解析。
表 4-1 status.yaml 推荐字段
| 字段 | 用途 |
|---|---|
status |
工作流状态(initialized / planning / developing / reviewing / merged / blocked 等) |
workflow |
所属工作流(development / testing / bugfix / merge-conflict / branch-op) |
branch |
Git 分支名 |
project |
所属项目名,决定 wiki 读写路径 |
tasks[] |
任务清单:id、标题、模块、所属仓库、依赖、验收标准、状态 |
deploy[] |
部署登记:仓库、环境、泳道、路由、版本、状态 |
guidance[] |
用户引导记录(pending / applied / rejected,详见第 8 章) |
log[] |
环节流转日志 |
4.4 第三层:项目长期记忆
存放于 wiki/<项目名>/,承载跨任务复用的稳定知识。这一层的信息形态应选择"带来源的段落式文档"------一条业务术语的解释、一条技术决策的来龙去脉、一个服务的部署地址,均需保留上下文叙事,不宜拆成孤立的键值对。
推荐分类如表 4-2 所示。每个分类目录下设 index.md 作为总索引。
表 4-2 项目 wiki 推荐分类
| 分类目录 | 收录内容 | 对应记忆类型 |
|---|---|---|
biz/ |
业务背景、术语定义、领域职责与不变量 | 语义记忆:从具体需求中提炼的业务常识 |
code/ |
仓库概览、术语到代码入口的映射、接口到业务场景的映射、长期分析 | 语义记忆:长期稳定的导航锚点 |
rule/ |
技术决策记录、工程约定与偏好 | 语义记忆:为什么这么定 |
config/ |
服务清单、部署环境、泳道、网关地址、租户账号、凭据获取方式 | 语义记忆:代码外的运维事实 |
history/ |
已关闭工作区的归档摘要(summary.md + run/) | 情景记忆:具体事件的压缩存档 |
注意分类与记忆类型的对应关系:space/ 下的过程产物是情景记忆 (记录"这个任务当时做了什么"),wiki/ 下沉淀的是语义记忆 (提炼出"这个项目的业务规则是什么"),harness/ 下的命令与状态机则是程序记忆(记录"这类事应该按什么流程做")。三者不应混放------情景记忆未经提炼直接进长期知识库,会污染语义层。
4.5 索引与小文件
长期知识库采用"索引 + 小文件"结构。每个分类目录下设 index.md,以表格形式列出该分类下的文件、主题与收录范围。索引仅作导航,不复制正文。内容按主题拆成独立小文件,高内聚、低耦合。
此结构的工程理由:上下文窗口有限,检索时应先读索引判断方向,再只读命中的小节。一个主题一个文件,既降低单次读取的 token 开销,也使文件在长期演进中保持可维护。
4.6 写入纪律
向长期知识库写入信息时,须遵守以下规则:
- 选择性写入。并非所有对话内容都值得长期记住。任务中的一次性细节("这次测试用了哪个账号")不写入;只有跨任务可复用的事实才沉淀。写入前先问:三个月后另一个任务会不会用到这条信息?
- 抽象化提炼。用户在任务中的具体纠偏("这个函数别这么写")应被提炼为通用规则("本项目此类函数统一采用 X 模式"),而非原样堆砌。提炼过程需经人工确认,避免模型过度泛化。
- 条目须标注来源。每条知识须注明出处:工作区产物(附文件路径与章节)、用户引导记录、Git 提交哈希、或用户资料。无来源的内容拒绝写入。
- 可信状态分级 。条目状态分为四级:
confirmed(用户或权威资料确认)、verified(已与代码交叉验证)、reported(单一来源陈述)、candidate(待确认)。后续任务加载上下文时,默认仅取前两级,后两级仅作线索。 - 矛盾不覆盖,保留演变。新事实与旧条目冲突时,就地更新为当前结论,并注明"此前为 X,于 Y 因 Z 修正"。技术决策被取代时,旧条目标记取代关系,不直接删除。此设计保留了知识演进的轨迹,使后续读者理解决策为何变化。
- 禁止以知识库更新知识库。知识库的事实来源只能是工作区原始产物、代码、Git 历史与用户原始资料;已有的知识库页面不得作为另一页面更新的事实来源。此规则防止 AI 合成内容在知识库内层层放大------一个未经证实的陈述一旦入库,就可能在后续被反复引用,成为看似权威的"共识"。
4.7 检索优先级
模型获取知识时按以下顺序下沉,不得在上层缺失时终止检索:
项目 wiki(跨任务共识)→ 当前任务的分析文档(临期结论,须校验基准 commit)→ 直接读取代码(最终事实来源)
上层缺失或存疑时必须下沉取证,不得因"知识库没写"而止步。知识库内容与代码不一致时,以代码为准。分析类文档头部应记录"基准 commit",重新检索时由脚本比对当前 HEAD,落后若干提交即提示结论可能过时。
5. 命令的表示与路由
5.1 命令文件结构
命令应以 Markdown 文件形式存放于 harness/cmd/,不应硬编码进框架代码。命令文件本质上是一份给模型的 SOP:明确前置条件、输入源、执行步骤与后置校验。文件头(front matter)即路由声明:
yaml
---
command: spec # 工作流文件用 workflow: development
short: sp
triggers: 需求规划, 整体设计, spec
summary: 产出需求规划文档
---
front matter 四个字段:command 为命令名,short 为简写,triggers 为中英文触发词(逗号分隔),summary 为一句话摘要。命令正文按"前置条件 → 输入源 → 执行步骤 → 后置校验"组织。
一个工作区可承载多个研发 story,分析产物按 story 分层:
space/20261001-user-login/
├── status.yaml
├── context.md
├── story/
│ └── <story>/
│ ├── analysis.md # 需求分析:现有实现、可行性、兼容性、待确认问题
│ ├── spec.md # 需求规划(顶层设计与公共契约)
│ └── plan.md # 开发计划(详细设计与施工图)
├── doc/
│ ├── tech-design.md # 技术评审文档(按需)
│ ├── test.md # 系统测试方案(按需)
│ ├── code-review.md # 代码审查报告(按需)
│ ├── release-check.md # 上线检查清单(按需)
│ └── analysis/ # 需求明确前的代码问答与分析记录
└── run/ # 可复用执行指令(按需)
5.2 路由脚本
配套实现一个路由脚本,核心职责为:遍历 harness/cmd/ 与 harness/workflow/ 下全部 .md 文件,解析 front matter,按用户输入匹配触发词,返回命中文件路径。Tack Harness 中 scan-routes.sh 的子命令约定:
bash
sh harness/script/scan-routes.sh list harness # 工作流表 + 命令表 + 可委派角色表
sh harness/script/scan-routes.sh workflows harness # 仅工作流(意图识别)
sh harness/script/scan-routes.sh commands harness # 仅命令
sh harness/script/scan-routes.sh agents harness # 仅可委派角色(不参与路由)
sh harness/script/scan-routes.sh resolve harness "需求规划"
行为约定:
- 唯一命中:输出命令文件路径,模型加载并执行;
- 多命中:输出候选清单,模型请求用户选择;
- 无命中:模型直接响应用户,必要时建议新建命令。
实现时建议将扫描、解析、匹配置于单个脚本进程内完成,避免在 Windows 平台为每个文件 fork 多次子进程。匹配英文关键词时采用词边界匹配(要求出现在词首或 - / _ 之后),中文关键词走子串匹配。
5.3 工具接口设计原则
命令与脚本本质上都是模型可调用的工具。工具接口的质量直接决定模型行为的可靠性。两条原则值得强调:
命名与参数须从模型视角设计 。命令名应与用户自然语言中的说法对应,触发词覆盖中英文常用表述。一个需要反推才能理解的命令名,等同于不存在。Tack Harness 中所有命令均支持中英文触发词与简写(如 需求规划/spec/sp)。
让错误用法难以发生。高危操作(删除任务目录、强制推送、覆盖知识库)应在工具层面默认禁用,或要求显式参数确认,而非依赖提示词叮嘱模型"不要这么做"。结构上不可能发生的错误,比提示词里的禁令可靠得多。
6. 状态机与任务调度
6.1 状态机定义
模型在开放式任务中失效的主要原因,是缺乏对当前所处阶段的明确认知。须为每类典型研发场景定义状态机,存放于 harness/workflow/。Tack Harness 定义了五条工作流:
| 工作流 | 触发词 | 状态流转 |
|---|---|---|
| development | 需求开发 / 功能开发 / dev | initialized → planning → developing → reviewing → merged,close 后工作区注销 |
| testing | 补测试 / 测试任务 / tst | initialized → test-planning → testing → verifying → completed |
| bugfix | 修 bug / 修缺陷 / 排障 / bug | initialized → reproducing → diagnosing → fixing → verifying → completed |
| merge-conflict | 合并冲突 / 冲突工作流 / mc | initialized → fetching → merging → resolving → verifying → pushing → completed |
| branch-op | 分支操作 / bop | initialized → preparing → integrating(冲突时 resolving)→ pushing → completed |
任意环节受阻可进入 blocked 状态(在 status.yaml 中记录阻塞原因),解除后回到原状态。开发主链路如下:
flowchart LR A"init" --> B"work 需求" B --> B2"analyze 需求分析" B2 --> C"spec" C --> D"plan" D --> E"tech-design" E --> F"code" F --> H"fetch" H --> I"commit" I --> J"push" J --> K"merge" K --> L"close" B -. 需求明确前可选 .-> A1"ask" F -. 用户需要时触发 .-> G"testcode" F -. 用户需要时触发 .-> G2"test" F -. 用户需要时触发 .-> G3"run" C & D & E & F -. 发现偏差 .-> M"fix" M -. 需求修正回环 .-> C K -. 冲突 .-> N"solve" N -.-> K
6.2 主链路固定,边界内放权
状态机的设计意图不是把模型的每一步都写死,而是守住"必须经过哪些环节"的边界。主链路(需求分析 → 方案设计 → 编码 → 审查 → 合并)由状态机约束,不得跳步;但每个状态内部"怎么写这段代码""选哪个方案",完全交给模型判断。
这是工作流与自主 Agent 的折中:能预先分解为固定步骤的环节,用状态机约束路径;需要动态决策的环节,保留模型自由。
6.3 任务调度
plan 阶段产出的任务清单写入 status.yaml 的 tasks[],每条包含 id、title、module、repo、deps、acceptance、status 字段。任务领取与完成须由脚本原子操作,避免多模型实例并行时重复领取:
- 校验依赖已满足后将任务状态置为进行中;
- 完成当前任务后返回下一个就绪任务;
- 状态迁移支持 pending / in_progress / done / blocked。
6.4 按需命令
测试、代码审查、上线检查等命令不应挂在主链路上。它们不占用状态位、不阻塞主流程、模型不主动询问是否执行;用户明确提出时才触发。Tack Harness 中的按需命令包括:testcode(单测驱动的需求-代码一致性审查)、test(系统测试方案)、run(可复用脚本执行)、code-review(合并前独立审查报告)、release-check(上线检查清单)。此设计避免重流程对简单任务的强制约束------一个改动两行的需求,不应被迫走完完整测试与审查流程。
6.5 自动流转
提供 auto 命令自动执行当前工作流剩余环节到终态:开始前一次性补齐缺失信息并确认全流程,确认后连续执行不中断,结束时汇总关键决策与结果。默认到 merged / completed,可指定一并 close。
7. 脚本与模型的职责划分
划分原则为:可确定性执行的操作全部脚本化,需语义判断的环节交由模型处理。典型划分如表 7-1 所示。
表 7-1 脚本与模型的职责边界
| 操作类型 | 执行方 | 划分依据 |
|---|---|---|
| 多文件状态字段批量更新 | 脚本 | 机械、高频、要求精确(work-status.sh) |
| Git 批量 add / commit / push / worktree 管理 | 脚本 | 高频、易出错、要求原子性 |
| 命令路由扫描 | 脚本 | 每次会话均需执行,不应消耗 token(scan-routes.sh) |
| 知识库索引完整性校验 | 脚本 | 可机器判定,须门禁 |
| 凭据模式扫描 | 脚本 | 高置信规则,误报可控(scan-secrets.sh) |
| 工作区创建与目录批量登记 | 脚本 | 机械操作,保证一致性 |
| 升级三方比较与基线管理 | 脚本 | 需精确比对出厂原件与本地差异 |
| 需求拆分与 story 划分 | 模型 | 需语义判断 |
| 技术方案选型 | 模型 | 需结合上下文权衡 |
| 缺陷定位与假设生成 | 模型 | 需探索与推理 |
| 代码审查结论 | 模型 | 需逐函数语义判断 |
背后的判断逻辑:通用探索类能力(读写文件、执行命令、搜索代码)交给模型自由组合;高风险或强约束类操作(凭据入库、分支删除、强制推送)封装为专用脚本,默认禁用或需人工确认。判断准则:若某条提示词指令描述的是固定动作序列,应将其实现为脚本,而非依赖模型每次自觉执行。
脚本须保证三平台可移植性(Linux / macOS / Windows Git Bash),统一按 POSIX sh 编写;Tack Harness 中 lint-shell-portability.sh 随结构检查运行,检出裸 mktemp、GNU 专有选项、bashism 与 sed 方言问题。
8. 经验沉淀闭环
缺乏沉淀机制的工作流将在数周内退化为无约束的自由对话。须建立"采集---固化---校验"三步闭环。
8.1 采集
任务执行过程中,凡用户对模型行为提出纠正或补充约定,均以原始事实追加至 status.yaml 的 guidance 列表,每条记录包含:发生时间、所在环节、场景描述、用户原话事实、状态(pending 待固化)。此阶段仅记录事实,不做语义抽象,不修改任何规则文件。
8.2 固化
任务结束时(close 命令收尾时),将待固化条目列表提交用户审阅。审阅依据为:该条是否跨任务可复用?是长期规则还是单次任务特例?用户确认后,先扫描现有命令与规则文件,存在相关条目则就地融合,确无合适条目时方新建文件。经用户拒绝的条目标记为 rejected;用户暂未决断的条目保留 pending 状态。
这一步的关键是"延迟判断":纠偏发生时先记录,不在情绪上头时立即改规则;任务结束后有上下文距离,再判断这条纠偏是应该固化为长期规则,还是仅适用于本次任务。
8.3 校验
落盘完成后,脚本校验目标文件真实存在,再将对应 guidance 条目标记为 applied;路径不存在则阻断写入并报错。此步骤防止沉淀出指向空气的引用。
8.4 三条补充通路
除自动闭环外,建议提供三条手动命令:
- record(手动沉淀):用户主动要求记录某条知识时,先扫描已有命令尝试融合修正;可落命令、工作流、规则、wiki 或 AGENTS.md 常驻约束;新建时仅需提供 command,简写与中英文触发词自动生成;
- evolution(对内审查):校准空间登记与实际目录、检查 wiki 索引完整性、lint 框架结构与脚本签名、审查全部指令,提炼 rule/reference/script 候选、清理过时事实;
- study(对外学习):读取外部 skill 或仓库的设计,提炼可借鉴做法落盘到 harness 对应位置,统一预览确认后提交,随后自动执行一次增量 evolution。
9. 评审的证据绑定
代码审查与上线检查须引入证据指纹机制,解决"评审完成后输入变化但结论仍被沿用"的问题。
具体做法:评审开始前,对本次评审的全部输入计算哈希指纹,覆盖范围包括:需求文档、规则文件、仓库 HEAD、目标分支引用、暂存 diff、未暂存 diff、未跟踪文件内容。评审者完成评审后,须凭脚本返回的令牌确认评审结论;脚本重算指纹并核对令牌一致,才记录"已评审"。评审期间任何输入变化均导致指纹不匹配,令牌自动失效。
同类机制可用于阶段确认:需求分析、方案设计等阶段经用户确认后,存储一份绑定文档哈希的回执。任务中断后恢复时,仅重读指纹变化或未确认的阶段文档,避免全量重读。
此机制的本质是把"我看过了、我同意了"从一句模糊陈述,转化为可机器校验的事实快照。
10. 隔离与安全约束
以下机制以较低成本提供必要的安全边界。设计思路一致:能在结构上避免的错误,不依赖提示词叮嘱。
- 代码改动隔离 :主仓库
repo/设为只读基准,任务代码修改在space/<工作区>/repo/的独立 worktree 中进行。多个任务可并行开发不同需求,互不干扰。误操作主仓库在物理上不可能发生。 - 危险操作禁用 :在
harness/rule/中明确禁止push --force、commit --no-verify、reset --hard、直接修改主仓库等操作。 - 空间级互斥:空间根仓库的状态写入与自动提交须串行化(空间锁)。持锁进程被强杀或中断后,残留锁按 pid 存活检测自动回收,存活持锁者仍正常阻塞。
- 凭据扫描门禁 :文档提交前执行
scan-secrets.sh,匹配高置信凭据模式(私钥头、云厂商 Access Key、Token 前缀等),命中即阻断自动提交。占位值(your-、example、<...>模板)与显式豁免标记不告警。 - 删除目录校验 :工作区目录删除前须通过三道校验------路径须为单层目录名(拒绝分隔符与
..)、物理路径须确认位于space/内(防符号链接逃逸)、repo/下无残留 worktree。 - 分支清理门禁 :close 时仅处理
status.yaml登记的分支,默认 dry-run;未合并主分支、保护分支、被 worktree 占用的分支与主干不明项只列出不删除,远端分支不自动删除。 - 人工审批节点:分支合并、版本发布、工作区删除三类操作,须经用户明确确认后方可执行。提交由用户主动发起 commit 命令触发(发起即确认意图,信息自动生成后直接提交)。
11. 可复用脚本的组织
测试、数据迁移等重复性操作宜组织为独立指令目录,而非每次临时编写脚本。推荐结构:
space/20261001-user-login/run/
├── run.md # 说明书:用途、依赖、人工步骤说明(只做识别、索引与编排)
├── <指令1>/
│ ├── setup.sh # 具体脚本
│ ├── load-data.sh
│ └── local/ # 凭据与环境数据(gitignore,不入版本库)
└── <指令2>/
└── ...
run.md 只做识别、索引与编排,每条指令的脚本、数据与凭据各自成目录(local/ 不入库)。执行时校验清单完整性、按序执行、失败即停、支持显式续跑与人工步骤确认。任务 close 时,run/ 整体归入 wiki/<project>/history/<workspace>/ 归档,脚本可在后续需求中直接复用。
12. 实施路径
建议按以下节奏分阶段落地:
第一周 :仅建立 AGENTS.md 与三条最常用命令(启动任务、编写代码、提交收尾)。状态文件以 YAML 手工维护。在一个真实需求上跑通完整流程。
第二至四周 :依据实际使用中暴露的痛点逐步补充。例如:频繁手工修改状态时,编写状态回写脚本;知识库结构混乱时,补充索引规则并编写完整性校验脚本;模型反复违反某条约束时,将其提升至 AGENTS.md。
第二个月:启用经验沉淀闭环。此时已积累足够数量的用户纠偏记录,具备固化为规则的素材基础。同时引入证据指纹与隔离 worktree,处理多任务并行与代码审查的可靠性问题。
不建议在未经历实际使用的情况下追求流程完整性。工作流应从真实痛点中生长,而非预先设计。模型能力在持续演进,今天需要脚本兜底的环节,明天可能被模型原生能力内化;因此工作流应保持精简,把节省下来的结构复杂度,留给那些模型暂时还做不稳的地方。
附录:最小可用版本
以下结构可在半小时内搭建完成:
my-project/
├── AGENTS.md # 约 30 行的常驻说明书
├── tack.yaml # 空项目登记
├── harness/
│ ├── cmd/
│ │ ├── work.md # 建工作区:建目录、写 status.yaml 与 context.md
│ │ ├── code.md # 编码:按 plan 执行
│ │ └── close.md # 提交收尾:归档、沉淀、清理
│ ├── workflow/
│ │ └── development.md # 主链路状态机
│ ├── script/
│ │ └── scan-routes.sh # 命令路由(约 100 行)
│ └── rule/
│ └── security.md # 三条禁令
├── wiki/
│ └── <project>/
│ └── index.md
└── space/ # 工作区目录随用随建
如果不想从头搭建,可以直接以 TackHarness 为基础做修改,完整源码可见:Github。在真实任务中使用两周后,依据遇到的具体问题迭代扩展,最终形成与个人或团队的实际研发习惯一致的工作流。
TackHarness 安装
以下方式二选一即可。
-
由 Agent 自行安装(推荐),在Claude Code、Cursor、TRAE、Codex 等编程 Agent 中输入:
-
一键安装脚本,在shell终端输入:
bash
curl -fsSL https://raw.githubusercontent.com/frcoder-lh/tack-harness/master/install.sh | sh -s
TackHarness 使用
# 初始化TackHarness空间
/tack
# 查看帮助文档
/tack help