Back to skills
SKILL.md
Control
ASecurity仅手动触发。用户显式调用 $control 查看或推进 docs/00-任务总控/ 下的活跃总控时使用。只执行用户指定的 Tn,回填状态后立即停止,禁止顺带推进相邻子任务。
- 6 stars
- 0 votes
- 0 copies
- 1 view
- Added September 5, 2026
Security analysis
100/100Pro scans all 14 files and shows the line behind each finding
npx -y skills add BackToCimaCoppi/Praxis --skill control --agent claude-codeAre you the author of Control?
Add the live security badge to your README. It updates with every re-scan.
[](https://www.skillsdirectory.com/skills/backtocimacoppi-control)---
name: control
description: "仅手动触发。用户显式调用 $control 查看或推进 docs/00-任务总控/ 下的活跃总控时使用。只执行用户指定的 Tn,回填状态后立即停止,禁止顺带推进相邻子任务。"
---
# Control
按当前项目 `docs/00-任务总控/` 下的总控文档推进任务。本 skill 是**通用方法论 skill**(用户级),不绑定具体项目。
**真值源**:`references/总控规范.md`(本 skill 内)。
---
## 🛑 执行边界(最高红线,永远遵守)
> 这是本 skill 最重要的一条。所有其他规则都让位于此。
1. 用户指定 `$control <key> Tn` → **只执行 Tn**(支持 `Tn.x` 二级子任务)。不做 Tn-1,不做 Tn+1,不做同级兄弟,不"顺手"做相关任务。
2. Tn 的「输出物」全部产出 → **立刻停止,回填状态,向用户报告**。等用户下一步指令。
3. ✅ **读不设禁区**:可以读其他子任务详情与产出物、总控任何部分、仓库任何文件——开工前把背景挖够再动手(读什么放开 ≠ 做什么放开)
4. ❌ 不可写入其他子任务范围(即使发现"很容易顺便做"也不要做)
5. 如果发现 Tn 的**范围定义**有问题(应扩大或缩小) → **停止施工,向用户报告问题**,不要自行扩张。但**"工作包某句描述过时了"不是范围问题**——与已冻结上游冲突时,按最新冻结真值修订描述、留痕、继续跑(总控规范 §4.6)
6. **自主补读亲自读**:为补背景直接读文件 / 检索即可,**禁止为"补背景"派子 agent / 起深度调查**(读是加法、派 agent 是乘法);背景缺口大到需要专门调查 → 按第 5 条停机上报,不自己扩编
7. **过程资产边界**:执行 Tn 时产生的中间文档(设计稿、清单、批判稿等),只能写到 `_shared/` 且文件名带 `T{n}-` 前缀(任务级共享资产无前缀);**不可**用其他子任务的 `T{m}-` 前缀(m≠n),**不可**平铺到任务根目录,**不可**新建 `_T{n}/` 目录。详见总控规范 §1.1.1。
8. **规则铸造权不在工作包手上**:只有项目级指令文档与 skill 能铸造规则。工作包 / 评审报告 / goal 章程里的「硬门」「死亡线」「必须审批」**一律是执行建议,不具停机权**;**死亡线是封闭清单,任何人无权新增**——包括你(总控规范 §4.4)
9. **停机白名单封闭,只有三条**:①两份**都已冻结**的真值真矛盾且改变业务结果 ②命中项目死亡线清单的**业务规则**要变 ③不可逆 / 外发动作。**其余一律先修后报**——笔误、脚本 bug、过期描述、证据充分的简单缺陷,在预授权边界内修复 + 留痕 + 继续。减少临时协调不覆盖项目声明的授权角色、环境占用、职责分离或强制检查点。冲突批处理与 `EXECUTION_BLOCKED` 细则以总控规范 §4.5 为真值;goal 执行态以章程 §4 白名单为准(章程已由对应权限角色预授权的动作不触发第 ③ 条)
10. **获批总控可包含本地提交授权**:只有经任务治理负责人批准的总控,才预授权在其范围内 `git commit`;项目补丁可要求额外检查。**推送远端仍需发布授权人显式授权**(总控规范 §4.7)
11. **写入范围必须机器核对**:开工记录 `start_commit`;工作包列出 `allowed_write_paths` 与精确到 Markdown 标题的 `allowed_cross_task_writes`;交付前只对本子任务明确列出的候选提交运行 `check_write_scope.py`。无关提交不阻断,候选提交夹带越界文件直接失败(总控规范 §4.8)
12. **长程 goal 必须磁盘复水**:首次启动、`--resume`、新会话或自动上下文压缩后,第一次写入前重读当前工作包、全部强制阅读、章程、goal 断点与飞行日志尾部;连续未压缩轮次不机械复读整套 skill(总控规范 §4.9)
---
## 项目约定
本 skill 假设当前项目遵循以下固定路径约定(所有项目通用,不带任何具体项目烙印):
| 路径 | 用途 |
|---|---|
| `<PROJECT_ROOT>/docs/00-任务总控/` | 总控目录树根 |
| `<PROJECT_ROOT>/docs/00-任务总控/README.md` | 活跃任务索引 |
| `<PROJECT_ROOT>/docs/00-任务总控/归档/` | 已完成任务归档树 |
| `<PROJECT_ROOT>/docs/00-任务总控/归档/README.md` | 归档总索引 |
| `<PROJECT_ROOT>/docs/00-任务总控/归档/V{x}/README.md` | 版本归档索引 |
| `<PROJECT_ROOT>/docs/00-任务总控/{YYYY-MM-DD}-{任务名}/` | 任务子目录(**日期前缀防多 worktree 编号撞车**) |
| `<PROJECT_ROOT>/docs/00-任务总控/{YYYY-MM-DD}-{任务名}/README.md` | 任务主总控(拆分 / 单文件统一) |
| `<PROJECT_ROOT>/docs/00-任务总控/{YYYY-MM-DD}-{任务名}/T{n}-{子任务名}.md` | 拆分模式的一级子任务工作包 |
| `<PROJECT_ROOT>/docs/00-任务总控/{YYYY-MM-DD}-{任务名}/T{n}/T{n}.md` | **被拆过**的父任务说明(保留背景/范围,原 T{n}-*.md 迁移到此) |
| `<PROJECT_ROOT>/docs/00-任务总控/{YYYY-MM-DD}-{任务名}/T{n}/T{n}.{m}-{子任务名}.md` | 二级子任务工作包(split 后产生) |
| `<PROJECT_ROOT>/.agents/local/active-control` | per-worktree 激活配置(gitignored) |
| `<PROJECT_ROOT>/.gitignore` | 必须包含 `.agents/local/` |
**项目根解析**:脚本通过 `find_project_root()` 自动定位 —— 优先 `PRAXIS_PROJECT_ROOT` 环境变量,回退 `git rev-parse --show-toplevel`。仓库外执行报错。
**新项目首次使用**:跑一次 `scripts/bootstrap_project.py` 自动建好骨架。详见下面「触发模式 / `$control init`」。
---
## 🔒 `$control status` 输出契约(硬规则)
> 这是为了消除"AI 看到脚本输出后自由排版"的问题。**所有 status 类查询的最终呈现以脚本输出为准。**
触发条件(任一):
- `$control list`
- `$control status`
- `$control <key> status`
- 用户用同义说法询问任务列表 / 进度 / 现在做到哪儿了 / 给我一个总控任务表
> **已知失效模式(必读)**:工具调用的 stdout 在部分客户端界面上会被直接渲染出来,AI 因此容易产生"用户已经看到了,我只需要追加一句结论"的错误判断,转而只输出一行总结(如"下一步可执行 Tn")而跳过表格本身。**这个判断是错的**——第 2 步要求的是 AI **自己的最终文字回复**里包含完整表格,不是"工具输出已展示"就算数。跨模型/跨客户端都会犯这个错,必须靠下面的显式自检堵住,不能靠"应该记得"。
执行步骤:
1. 调用 `render_control_status.py`(带或不带关键词,按触发模式)
2. **逐字复述**脚本 stdout 输出到自己的最终文字回复正文中(不是"已经调用过工具就算展示过"),包含但不限于:
- 块头(`# 总控状态` / `# 活跃总控`)
- 派生总体状态行
- 任务统计行
- 顶部附注行(如有)
- 完整子任务总表(所有列:编号 / 子任务 / 状态 / 依赖 / 预期输出)
3. **禁止**:重排版、合并行、省略列、改列名、调整列顺序、给数据加省略号、把表格转成 bullet list、跨多任务时只输出部分
4. **允许**:表格之后追加**最多一段**简短"下一步建议",格式必须从下列固定模板选一条:
- 「下一步可执行:`Tn`(依赖已满足)」—— 存在可执行子任务
- 「全部完成,可调用 `archive_control.py --apply` 归档」—— 派生状态 = 已完成
- 「存在阻塞:`Tn`,请对应授权角色裁决」—— 派生状态 = 阻塞
- 「未启动,请任务调度负责人决定从哪个子任务开始」—— 派生状态 = 未启动
5. 用户没有问下一步时,第 4 步可以省略;不主动追加其他解读
6. **发送前自检(发送前必做,不可跳过)**:在写下最终回复的最后一刻,反问自己——"如果去掉我调用的工具,只看我这段文字本身,用户能不能看到完整子任务总表?" 答案是"不能"(比如正文只有"下一步可执行:Tn"这类总结句,表格本身没有出现在文字里)→ 视为本次回复不合格,必须重写,把步骤 2 的完整表格文本真正写入正文后再发送。
错误处理:脚本报错(找不到总控 / 多候选 / 缺列)→ 把脚本的错误原文展示给用户,再询问应该怎么处理;不要"修复式 freestyle"。
---
## 触发模式
| 模式 | 作用 |
|------|------|
| `$control init` | **新项目首次使用**:建 docs/00-任务总控/ 骨架、追加 .gitignore(幂等) |
| `$control list` | 列出所有活跃总控(最少上下文) |
| `$control status` | 只读查看当前总控状态表 |
| `$control <关键词>` | 进入指定总控,列出可执行子任务,等用户选 |
| `$control <关键词> Tn` | 执行指定子任务(严格边界,支持 `Tn.x` 二级子任务) |
| `$control <关键词> status` | 查看指定总控状态 |
| `$control <关键词> split Tn` | 把一级父任务 Tn 拆为二级子任务 Tn.1 ~ Tn.N(用户必须先和 AI 对齐边界) |
| `$control blocked` | 列出所有阻塞子任务 |
| `$control switch` | 列出所有活跃总控,**交互式**让用户选一个写入激活指针 |
| `$control use <关键词>` | 直接按关键词设置激活总控(已知目标时用,比 switch 快) |
| `$control use --clear` | 清除激活配置 |
| `$control use --show` | 显示当前激活配置 |
**关键词省略时的目标选择优先级**:
1. 显式 `<关键词>`(用户传了就用这个)
2. `.agents/local/active-control` 文件指向的任务(多激活时显式指定)
3. 唯一兜底:只有 1 个未归档总控时直接选中
4. 否则报错列候选,要求加关键词或运行 `$control use <key>`
多候选时停止并让用户选择。
---
## 强制阅读(按粒度递增)
> **核心原则**:触发的命令越具体,读的文件越精准。**不要预先读所有文件**。
| 触发模式 | 必读文件 | 默认不读(非禁区) |
|---------|---------|------|
| `$control init` | 无(直接调脚本) | — |
| `$control list` | `<PROJECT_ROOT>/docs/00-任务总控/README.md` | references/总控规范 / 各总控正文 |
| `$control <key>` 或 `$control <key> status` | 上 + 目标主总控 README.md 的「任务背景」「子任务总表」 | 子任务详情段、其他子任务、references |
| `$control <key> Tn` 或 `$control <key> Tn.x` | 上 + **该子任务详情** + 它列出的「强制阅读」文件 | 其他子任务详情、references |
| `$control <key> split Tn` | 上 + **Tn 父任务详情**(用于和用户对齐拆分边界) | 其他子任务详情 |
| 创建新总控 | `references/总控规范.md` + `task-control-doc` skill | — |
| 归档任务 | `references/总控规范.md` §2.3 + 归档目录索引 | — |
`AGENTS.md` 由会话级注入,不需要再读。
> **「默认不读」管的是成本,不是禁区**:status / list 类只读查询别把全库读一遍。但一旦进入 **Tn 执行**,执行者可以且**应该**按需补读——「背景导航」(如有)、其他子任务详情、相关正式文档、代码现状,把背景挖够再动手(见执行流程 §3 与执行边界第 3、6 条)。旧版把「不读」当禁令,是为弱模型防上下文污染设计的;强模型时代背景不足导致误判的代价远大于多读几个文件。
---
## 自动化脚本
| 脚本 | 对应触发模式 |
|------|------------|
| `scripts/bootstrap_project.py` | `$control init` |
| `scripts/render_control_status.py --list` | `$control list` |
| `scripts/render_control_status.py [关键词]` | `$control [关键词] status` |
| `scripts/next_subtask.py [关键词]` | `$control [关键词]`(含完整会话启动提示词) |
| `scripts/next_subtask.py [关键词] --show Tn` | `$control [关键词] Tn` —— dump 子任务详情段(支持 `Tn.x`) |
| `scripts/split_subtask.py <关键词> Tn --subtasks "Tn.1=名1,..." [--apply]` | `$control [关键词] split Tn` —— 拆分(默认 dry-run) |
| `scripts/check_write_scope.py ...` | 对本子任务候选提交做写入范围与跨任务 Markdown 段检查 |
| `scripts/list_blocked.py` | `$control blocked` |
| `scripts/render_control_status.py --list` → 用户选择 → `scripts/set_active.py <精确名>` | `$control switch` |
| `scripts/set_active.py <关键词>` / `--clear` / `--show` | `$control use ...` |
| `scripts/archive_control.py <关键词> --version V1 [--apply]` | 归档(默认 dry-run) |
```bash
SKILL_DIR=~/.agents/skills/control/scripts
# 新项目首次初始化(幂等)
python3 $SKILL_DIR/bootstrap_project.py
# 最少上下文:只列活跃总控
python3 $SKILL_DIR/render_control_status.py --list
# 列指定总控的子任务概览
python3 $SKILL_DIR/render_control_status.py <关键词>
# 推荐下一个可执行子任务(输出含完整会话启动提示词,可复制即用)
python3 $SKILL_DIR/next_subtask.py <关键词>
# Dump 指定子任务详情段全文(用户已知做哪个,直接看完整工作包)
python3 $SKILL_DIR/next_subtask.py <关键词> --show T3
# 阻塞盘点
python3 $SKILL_DIR/list_blocked.py
# 交互式切换激活总控($control switch)
# 步骤:① 列出所有活跃总控 ② 向用户展示编号列表 ③ 用户选择 ④ 写入指针
python3 $SKILL_DIR/render_control_status.py --list # ① 获取候选列表
# → AI 把列表以编号形式呈现给用户,等待选择
# → 用户选定后执行:
python3 $SKILL_DIR/set_active.py <用户选中的精确目录名> # ④ 写入指针
# 直接按关键词设置激活总控($control use,已知目标时用)
python3 $SKILL_DIR/set_active.py <关键词>
python3 $SKILL_DIR/set_active.py --show
python3 $SKILL_DIR/set_active.py --clear
# 归档(默认 dry-run)
python3 $SKILL_DIR/archive_control.py <关键词> --version V1 --apply
# 拆分父任务(默认 dry-run,--apply 才写盘)
python3 $SKILL_DIR/split_subtask.py <关键词> Tn \
--subtasks "Tn.1=表设计,Tn.2=接口契约,Tn.3=Migration" \
--reason "Tn 工作量超出预期" --apply
# 子任务交付前:仅检查明确属于本子任务的候选提交
python3 $SKILL_DIR/check_write_scope.py --repo . \
--start-commit <开工SHA> --candidate <候选SHA> \
--allow 'src/目标/**' \
--allow-cross 'docs/00-任务总控/.../README.md::子任务总表'
```
---
## 执行流程
### 0. `$control switch` — 交互式切换激活指针
1. 运行 `render_control_status.py --list` 获取所有活跃总控
2. 若无活跃总控 → 提示先创建,停止
3. 若只有一个 → 直接写入,告知用户(无需选择)
4. 若有多个 → 以编号列表形式展示给用户(`1. xxx 2. yyy`),**等待用户回复编号或关键词**
5. 用户选定后运行 `set_active.py <精确目录名>` 写入 `.agents/local/active-control`
6. 输出确认:「已将激活总控切换为:xxx」
> **不读任何总控文档正文**,只需 `--list` 输出即可完成全流程。
---
### 1. 进入
1. 解析触发模式 → 确定需要的最小上下文(见上面的「强制阅读」表)
2. 用脚本获取索引信息(`render_control_status.py` 或 `next_subtask.py`)
3. 多候选时停止 → 列出候选,让用户选择
4. **不要自己解析总控文档**——脚本已经处理了
5. worktree 不绑定任务——任意 worktree 都可以切换激活总控。多激活时通过 `.agents/local/active-control` 文件确定默认目标,配置不存在且唯一总控时自动兜底
### 2. 子任务选择
用户没指定 Tn 时的优先级(已固化在 `next_subtask.py`):
1. 状态为 `进行中` 的子任务(恢复未完成工作)
2. 第一个 `待完成` 且依赖均已 `已完成` 的子任务
不跳过未解决的依赖。全部阻塞 → 报告原因并停止。
### 3. 执行(严格边界)
**开始前**:
- 子任务状态改为 `进行中`
- 读取工作包「写入范围」,在第一次写入前把当前提交记为 `start_commit`;目标路径若较模板发生变化,先修工作包范围再施工,禁止执行后补白名单
- 重新从磁盘读取该子任务详情和「强制阅读」文件——**不依赖聊天历史**
- 若为 goal 首次启动、恢复、新会话或自动压缩后的续跑,同时读取章程、`T{n}-goal断点.json` 与飞行日志尾部;先复水再产生任何写入
- **主动补读背景**:「背景导航」(如有)、其他子任务详情、相关正式文档、代码现状——把背景挖够再动手,不要仅凭工作包内容硬猜
- 自主补读**亲自读**(直接读文件 / 检索),不为补背景派子 agent / 起深度调查;背景缺口大到需要专门调查 → 停机向用户报告(工作包没写清,见执行边界第 5、6 条)
- 由用户在新会话开头自行选择模型(不在总控里预定义)
**执行中**:
- 改动严格限于「要做的事情」描述的范围
- 每个本子任务提交保持单一职责,不夹带无关文件;仓库中的其他提交/工作树变化不自动归给本任务,也不因其存在停机
- 遵守「不做什么」字段(如有)
- 子任务详情有「会话启动提示词」时按它走
- 遵守项目本地的真值优先级与同步规则(项目自身的 AGENTS.md)
**完成后**:
- 先提交本子任务变更,再把这些精确候选提交逐个传给 `check_write_scope.py`;越界时回退本子任务内容或补做真实上游范围裁决,禁止事后扩白名单让检查变绿
- **立刻停止**,不要继续做下一个子任务
- 回填总控(见下面的「回填」段)
- 向用户报告完成情况,等下一步指令
### 4. 回填
子任务完成后更新:
- 子任务总表「状态」 → `已完成`
- 子任务详情「当前状态」 → `已完成`
- 子任务详情「输出物」 → 实际产出文件列表
- 子任务详情「风险与注意事项」 → 新发现的残余风险(如有)
- 总控的「进展记录」追加一行:`- YYYY-MM-DD:[子任务编号] 完成,[简要摘要]`
阻塞时设为 `阻塞`,写明:阻塞什么、为何阻塞、最佳下一步。
### 5. 派给外部 agent 时
主流路径:用户在新会话执行子任务时,直接复制子任务详情末尾的「**会话启动提示词**」(或 `next_subtask.py` 输出末尾生成好的版本)。
如需主线程内 spawn agent(少数场景),prompt 必须注入边界声明(见 `references/总控规范.md` §4.3):禁止接管任务调度、只做指定编号子任务。
### 5.5 `$control <key> split Tn` —— 中途拆分父任务
> 触发场景:用户在执行过程中发现某个一级任务 Tn 太大、单一会话做不完,需要原地拆为 Tn.1 ~ Tn.N 二级子任务继续推进。
**核心约束**:
- 只允许两级层次。`Tn.x` 不能再拆,深层拆要么开新总控、要么改设计
- **AI 不可自行决定拆分粒度** —— 必须先与用户对齐:拆几个、各自做什么、依赖顺序
- 用户对齐后才调脚本生成骨架,脚本写完只是占位,子任务详情仍由用户/AI 后续填写
**执行流程**:
1. 用户敲 `$control <key> split Tn`,或用自然语言"把 T3 拆一下"
2. AI 读取 Tn 父任务详情(用 `next_subtask.py --show Tn`),向用户呈现当前状态
3. AI **询问**用户:要拆为几个子任务、每个子任务负责什么、命名建议是什么
4. 用户答复后,AI **重复一次拆分计划**让用户确认("拆 T3 为:T3.1=表设计、T3.2=接口契约、T3.3=Migration,理由:T3 工作量超出预期 —— 确认吗?")
5. 用户确认后调脚本(默认 dry-run,预览改动):
```bash
python3 $SKILL_DIR/split_subtask.py <key> Tn \
--subtasks "Tn.1=...,Tn.2=...,..." \
--reason "..."
```
6. dry-run 输出无异常 → 加 `--apply` 真正写盘
7. AI 简要报告改动:父任务状态自动派生、子任务骨架已生成、提示用户后续要补全各子任务详情
8. **不要顺手开始执行任何子任务** —— 拆分完毕,等用户决定下一步
**拆分后的数据语义**:
- 父任务 Tn 在总表状态列写 `派生`,渲染时由脚本聚合子任务实际状态显示
- 原来对 Tn 的依赖(如 T(n+1) 依赖 Tn)保持不变,语义自动变为"所有 Tn.* 完成"
- 父任务**不会**再被 `next_subtask.py` 推荐执行;只有叶子节点可执行
- 归档校验只看叶子状态;派生父跳过
**拒绝场景**(脚本会自动报错):
- 拆已完成 / 已取消的任务
- 拆子任务(Tn.x 不可再拆)
- 拆已经被拆过的父任务(不允许"追加",要追加请手动改总表)
- 子任务清单少于 2 个 / 编号不从 .1 起 / 编号不连续
---
### 6. 收尾与归档
任务整体完成时(不是子任务完成时) → 用户确认后调脚本:
```bash
python3 ~/.agents/skills/control/scripts/archive_control.py <关键词> --version V1 --apply
```
脚本自动同步索引并迁移目录到 `归档/V{x}/`。归档前会校验所有子任务必须为 `已完成` 或 `已取消`。
如该任务有专属 worktree,归档完后手动 `git worktree remove`。
任务被明确删除/放弃 → 见 `references/总控规范.md` §2.4(手动操作,不进归档)。
---
## 回复用户
摘要应包含:
- 目标总控文档 + 子任务编号
- worktree 状态(如适用)
- **改了什么 / 没改什么**(突出边界遵守)
- 残余风险(如有)
- 建议下一步(**不要主动接着做**)
Files in this skill
- SKILL.md
- agents/openai.yaml
- references/总控规范.md
- scripts/_common.py
- scripts/archive_control.py
- scripts/bootstrap_project.py
- scripts/check_write_scope.py
- scripts/list_blocked.py
- scripts/next_subtask.py
- scripts/render_control_status.py
- scripts/set_active.py
- scripts/split_subtask.py
- tests/test_check_write_scope.py
- tests/test_next_subtask_prompt.py
Attribution
Comments
Loading comments…
Newsletter
Get the weekly list of safe new skills, and the ones we pulled.