Files
workbuddy_skills/session-mechanism/graph/README.md
T
admin 4866ad8d37 feat(session-mechanism): 图模式补全自动化测试并接入技能入口
- graph/test_graphctl.py:新增 49 个用例,覆盖建图 / 校验硬错与警告 / 就绪集 /
  状态流转 / 非法操作 / 边界 / 写入范围隔离;实跑 Ran 49 tests OK(27.5s)
- graph/graphctl.py:修测试暴露的问题(+50/-10)
- graph/README.md:补「怎么跑测试」一节(+27 行)
- SKILL.md:目录树与入口指针登记 graph/(新增 4 行文档,机制行为零改动)
- 隔离性核对:collabd.py / goalctl.py / 两个看板 / 全部钩子 diff 为空;
  state.py 闸门读数绿、常驻心跳 7 秒、看板 20100 在听
2026-10-19 08:18:57 +08:00

116 lines
6.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 图模式(独立功能)
> 2026-10-18 新增。**这一套与现有「项目机制」完全并列**:不读写 `goal.json`、`tasks.json`、`collabd-state.json`,不参与六道闸,不接管常驻循环,不改变现有任何会话的行为。
> 停用方式:不调用它就行;它没有常驻进程、没有注册任何钩子、没有改任何现有文件。
## 一、它解决什么
现有机制是「一棒干一堆、由会话读摘要决定下一棒」。图模式把这层换成:
- **节点**:一块独立的活,带自己的**域**(允许写哪些目录)和**判据**。
- **边**:节点之间的依赖;依赖全 done 才放行。
- **状态**:写在一份图上,跨会话共享,不依赖任何会话的上下文。
于是可以做到:**一批就绪节点同时干、干完各自回报、下一批自动放行**。
## 二、怎么用
工作区参数 `--ws` 指向要被推进的工作区根目录。图落在 `<ws>/.workbuddy/graph/<gid>/`。
### 1、建图
按判据建(每条判据一个节点,默认无依赖、无域):
python graph/graphctl.py init --ws "<ws>" --title "目标名" --kpi "判据A;判据B;判据C"
按节点定义建(要并行、要依赖、要域,就用这个):
python graph/graphctl.py init --ws "<ws>" --title "目标名" --nodes-json - <<'JSON'
{
"max_parallel": 3,
"nodes": [
{"id": "A", "title": "改界面", "domain": ["ui/"], "accepts": ["页面能打开"], "deps": []},
{"id": "B", "title": "改文档", "domain": ["docs/"], "accepts": ["索引已登记"], "deps": []},
{"id": "C", "title": "改服务", "domain": ["server/"], "accepts": ["本地能起"], "deps": ["A"]},
{"id": "D", "title": "汇总", "domain": ["docs/index/"], "accepts": ["三处齐"], "deps": ["A","B","C"]}
]
}
JSON
### 2、校验
python graph/graphctl.py check --ws "<ws>" --gid "<gid>"
报三件硬错(环、依赖指向不存在的节点、状态非法)和三类警告(没有域、没有判据、两个节点域重叠)。
### 3、算这一批派谁
python graph/graphctl.py ready --ws "<ws>" --gid "<gid>"
输出 `ready`(这一批可以同时开工的节点)、`backlog`(就绪但被并发上限挡住)、`waiting`(还差什么)。
### 4、开一个节点、回报
python graph/graphctl.py start --ws "<ws>" --gid "<gid>" --node A --by "执行会话-xxx"
python graph/graphctl.py report --ws "<ws>" --gid "<gid>" --node A --state done --evidence "页面 1440 宽截图在 ui/shot.png"
回报 `done` 后会立刻返回下一批的 `ready`,这就是图在往前走的信号。
### 5、看状态
python graph/graphctl.py list --ws "<ws>"
python graph/graphctl.py show --ws "<ws>" --gid "<gid>"
## 三、就绪的四个条件
1. 依赖全部 `done`。
2. 节点自己是 `pending`。
3. 域不与任何 `running` 节点重叠(`docs/` 与 `docs/ui/` 算重叠)。
4. 加上在跑的节点后,不超过 `max_parallel`(默认 3)。
## 四、与现有机制的关系
| 事项 | 现有机制 | 图模式 |
|---|---|---|
| 目标定义 | `goal.json` | 图文件里的 `title` / `nodes` |
| 任务台账 | `tasks.json` | 图里每个节点的 `status` + `events.jsonl` |
| 派活决策 | 检查会话读摘要判断 | `ready` 按图算 |
| 触发 | 常驻 + 六道闸 + 静默 2 分钟 | 调用方驱动(人或会话),无后台进程 |
| 会话创建 | 自动化排期 | 由调用方决定(图不管怎么开会话) |
| 域锁 | 开工时声明 | 同左,节点的 `domain` 直接喂给开工命令 |
**两套可以同时存在**:图模式不读也不改现有那三份文件,现有机制也永远不会看到 `graph/` 目录。
## 五、怎么跑测试
python graph/test_graphctl.py -v
全绿应看到 `Ran 49 tests ... OK`,用时 20 秒上下(每条用例起一次子进程)。
测试只往临时目录写:`<GRAPH_TEST_TMP>/graph-test-<pid>/<用例名>`,默认 `GRAPH_TEST_TMP` = `AIProject/ai1net-dsh-server/tmp`,由每条用例的 `tearDown` + 进程退出的 `atexit` 兜底删除。想换落点就设环境变量 `GRAPH_TEST_TMP`。
清残留在本机是常态:跑完后 `tmp/` 下偶尔还能看到 `graph-test-<pid>/`(进程内已确认删空,是本机沙箱在进程退出后把删除路径又放回来了,与测试代码无关)。一条命令清掉:
rm -rf "E:/ProgramData/AIProject/ai1net-dsh-server/tmp"/graph-test-*
八个用例类各管一摊:
1、`T1_Init` —— 建图:`--kpi` 按条数生成节点(全角分号也认)、`--nodes-json` 带依赖与域、重复 id 报错、自动编号避让、`max_parallel`。
2、`T2_CheckErrors` —— 硬错三条:环(含自环)、依赖指向不存在的节点、状态非法。
3、`T3_CheckWarnings` —— 警告三类:无域、无判据、域重叠(`docs/` 与 `docs/ui/` 双向都算)。
4、`T4_Ready` —— 就绪集:依赖未满足、域与在跑冲突、超 `max_parallel`(running 占名额)、两个域重叠的节点不进同一批。
5、`T5_Flow` —— 流转:`pending→running→done`、`events.jsonl` 只追加、`blocked` 累加 `attempts`、回报后回带 `next_ready`。
6、`T6_Illegal` —— 非法操作:`running`/`done` 再 `start` 拒绝,`blocked` 可重开;`--state` 只认 `done` / `blocked`;不存在的节点/图报错。
7、`T7_Edge` —— 边界:单节点图、空节点图、gid 含中文(显式与自动生成各一条)、`list` 统计与空工作区。
8、`T8_Isolation` —— 独立性:工作区里预埋的 `goal.json` / `tasks.json` / `collabd-state.json` 跑完字节不变,且不新建这类文件,写入范围只有 `<ws>/.workbuddy/graph/`。
测试对 `graphctl.py` 的唯一要求是「能当命令行跑」,不 import 它的内部函数 —— 所以改内部实现不会连带改测试。
## 六、还没做的(下一步)
- 自动派活:读 `ready` 后自动建排期(要复用现有排期硬规则:cwds 正斜杠、workspace_scope、next_run_at 毫秒、scheduled_at ISO)。
- 判定节点完成:现在靠回报 `--state done`,还没有「看证据够不够」的自动判定。
- 回退边:`attempts` 已经在记,还没有「判不过回到哪个节点」的字段与规则。
这三件都只在本目录内加,不影响现有机制。