任务流程
每个状态变更的规则定义在 [references/estados.md](references/estados.md):每个变更为一张卡片,包含何时、由谁、需要什么授权、在仓库中做什么以及顺序。本文档说明如何使用它。
如何更改队列
所有队列的写入都必须通过CLI,绝不可手动编辑:
python -I -X utf8 "$HOME/.claude/sf/cola.py" [--raiz RUTA] [--quien propietario|principal] [--via cli|panel] [--json] <orden> …
- 始终使用此命令,在bash、zsh和PowerShell中均相同,适用于任何项目;子代理也遵循此规则。如果模型在会话开始时提示此机器上Python使用其他名称启动(在macOS上为
python3),则将python替换为该名称,此处及SF中所有Python命令均适用("Python命令来自检测到的解释器",第236条);cola.py encargo任务也会说明这一点。切勿使用某个文件夹中的tools/cola.py(在SF中,plugins/sf/tools/cola.py会随当前分支变化):起决定性作用的是已加载插件中的那个。加载时,面板会将其cola.py复制到~/.claude/sf/cola-<sesión>.py并启动它("面板执行加载时创建的cola.py副本",第136条);~/.claude/sf/cola.py是一个启动器,通过CLAUDE_CODE_SESSION_ID将命令传递给该副本:Claude和面板使用相同的ID(任务252)。若不存在副本,则返回2并提示:/reload-plugins可重新创建它。 --raiz:项目文件夹,默认为当前目录。用于测试时,可指定队列副本的路径。--quien:默认为principal;当变更是业主的决定时(例如批准关闭),使用propietario。- 返回码:0表示变更成功,1表示未执行变更(说明原因且未做任何修改),2表示命令格式错误;
choques仅用于查询,存在冲突时返回3。cola.py <orden> -h可查看每个命令的用法。
CLI在每次写入时执行的操作:锁定队列(.sf/peticiones.lock),先在.sf/copias/中保存一份副本(保留最近50个),在任务的historial中记录变更,如果任务移出队列,则将其连同历史记录移至.sf/historial.jsonl。任务编号不会重复使用。
CLI不执行的规则
CLI会检查每个变更的条件(起始状态、分支、步骤、git)。在对话中何时以及如何使用(注释、置为进行中、启动和回收子代理、建议测试和关闭、建议合并和重新描述、文档任务、自由操作等)由技能sf:orquestacion定义。此处仅涉及队列本身:
- 只有主开发者才能写入队列。 子代理不执行写入命令;它会在报告中说明,由主开发者执行。
- 所有请求都必须在进行中的任务下提出;否则不开始工作。重新组织队列(合并、拆分、重新描述、添加步骤、更改类型)不需要此前提("每个任务有一个活跃子代理时的编排",第149条)。
- 业主批准:
cerrar、a-observacion、reobservar和descartar需要等待批准;en-cola(从进行中放回队列)也需要批准,但仅在无工作时:如果其分支或子代理的辅助分支上有自己的提交,则不能放回队列;应关闭、观察或废弃("有分支的进行中任务不会放回队列",第170条)。如果分支为空或已删除,en-cola将删除该分支并回收空的子代理(第275条)。 - 创建时指定类型(
crear --tipo):deliberar(审议)、documentar(文档)、diseñar(设计)、implementar(实现)、especificar(规范)、corregir(修正)或investigar(研究);如果变更类型,使用tipo N T。 en-curso前的冲突检查:choques N,配合--archivos和预期文件(如果尚无分支,则从描述推断)。对于已在进行中的任务启动子代理时不检查("预测任务置为进行中时的冲突",第130条)。- 首次激活前建立分支(
rama),并发出警告。对于子代理,主开发者创建但不激活,并在启动子代理前进行标注(rama --sin-activar,subagente);子代理在其辅助分支上工作,主开发者使用git merge --ff-only合并。子代理从不激活任务分支到自己的 worktree:这样任务T和C即可与当前 worktree 配合工作("每个任务有一个活跃子代理时的编排",第149条)。 - 回收子代理:由CLI执行,根据
subagente标注的worktree和分支(--worktree接受相对于项目的路径),适用于所有将任务置于无子代理状态的命令:cerrar、a-observacion、descartar、eliminar、a-propuesta、revertir、limpiar、reabrir以及被合并任务中的fusionar(仅当其辅助分支已在保留的分支中;保留的分支保留其子代理)。非强制:有未提交更改的worktree、有未合并到develop的提交的辅助分支,或合并时未集成的分支,会保留并发出警告。相反,descartar和limpiar会移除所有内容,包括有未合并提交的辅助分支和有未提交更改的worktree:废弃意味着废弃所有内容(第189条)。cerrar和a-observacion会先拒绝,如果辅助分支有未合并到任务分支的提交,并说明如何合并。reabrir则会清除所有内容,包括有未提交更改的worktree且不发出警告:旧的worktree永远不会被重用。历史记录:recogida或recogida-con-avisos。主开发者仅需停止子代理并处理警告("cola.py在任务变为无子代理状态时回收子代理",第169条)。 - 提交签名("关闭提交的签名可配置;未配置则无签名行",第238条):
cerrar和a-observacion的压缩提交、decision的提交以及RELEASE版本的提交会包含来自.sf/proyecto.json的coautor行(在SF自身没有该文件的情况下,使用:Co-Authored-By: Claude Opus 5.5 <[email protected]>)。cerrar、a-observacion、decision和encargo接受--coautor "…",其优先级高于配置的行。如果两者都没有,则提交不包含合作作者行,encargo任务会向子代理说明这一点。 - 业主决策:
decision "Título" --archivo RUTA|--texto T [--numero NNN] [--coautor "Co-Authored-By: …"] [--push]不影响队列。它会分配develop分支中docs/decisiones/的下一个编号和文件名NNN-AAAA-MM-DD-titulo.md(若使用--numero,则重写该文件而不更改其名称);写入文件(如果文本未包含# Título,则添加;如果已包含,则必须匹配),重新生成README.md,并在develop分支上提交 "Decisión NNN: Título",即使当前有其他活跃分支也不改变或影响其工作副本,类似于a-propuesta(任务273)。如果develop位于其他worktree中,或者develop为当前分支但docs/decisiones/有未提交的更改,则不执行此操作。当develop为当前分支时,还会重新生成README.html。--push推送develop;输出编号和哈希值。如果没有git或没有develop分支,则仅写入文件并发出警告(任务283)。 - 合并与拆分由业主通过面板命令(
/sf_fusionar、/sf_split)发起;主开发者使用fusionar仅用于合并两个更新同一文档的任务("每个文档一个更新任务",第142条)。
各阶段命令
| 阶段 | 命令 |
|---|---|
| 创建与启动 | crear, choques, en-curso, en-cola, rama |
| 工作期间 | paso añadir, paso marcar, paso quitar, renombrar, tipo, subagente, informe |
| 测试 | listo, comprobado, probar |
| 关闭 | cerrar, a-observacion |
| 观察中 | observando, seguir, cerrar, reobservar,如果出现问题则 revertir |
| 撤销 | descartar, limpiar, revertir, reabrir, eliminar, restaurar, a-propuesta |
| 合并与拆分 | fusionar, split |
| 查询与备份 | lista, ver, copias, recuperar |
| 队列之外 | decision |
所有关闭操作(cerrar、a-observacion),无论是否有分支(包括提案),都要求完成“关闭任务”步骤,且没有其他待办步骤(“激活分支以便测试”除外)。这两个关闭步骤由cola.py在任务进入进行中状态时添加(crear --en-curso、en-curso、reabrir、从队列probar、restaurar、fusionar),只添加一次且位于最后,不能移除或更改文本;没有这两个步骤的进行中任务会在加载队列时自动获得。新的工作步骤如果已完成“激活分支以便测试”,会将其重新置为待办:需要重新测试。测试辅助步骤(paso añadir N "texto" --prueba)位于两个关闭步骤之间,关闭操作不要求它们,会保持原样,添加它们不会将“激活分支”重新置为待办("测试辅助步骤:在激活分支之后,关闭时不强制要求",第184条)。listo仅保存测试内容("关闭步骤,从任务进入进行中时起",第174条)。probar将develop合并到分支(如果存在冲突则回滚且不激活;如果子分支有未合并的提交则不合并也不激活),激活分支(如果已激活则保持),标记“激活分支以便测试”为已完成;cerrar也会执行此操作:业主的批准即是关闭(第172、121条)。步骤从1开始编号,对应于ver中的每个n。移出队列的任务会在.sf/historial.jsonl中记录其移出时的状态(cerrada、eliminada、absorbida、descartada以及(在回滚删除或保留待办之前,第134条)revertida),ver命令会显示这些信息。
回滚需要指定目标:revertir N --eliminar将任务从队列中彻底移除,如同删除操作;revertir N --pendiente将任务放回待办列表,处于队列中并重新打开,没有分支。永远不会使任务处于“已关闭”状态并附带R标签("回滚删除任务或将其保留为待办",第134条)。如果业主未指定,询问其选择。
当命令因git原因失败时(压缩或回滚时冲突、有未提交更改、分支位于其他worktree),CLI将回滚并说明原因;主开发者需解决后重复该命令。推送失败不会阻止关闭:状态记录为push-fallido,可手动重新推送。