chore(governance): add waiting task status
This commit is contained in:
@@ -52,7 +52,7 @@ MVP 以默认 16 路跑通一个场景的端到端闭环;架构、数据和 UI
|
||||
|
||||
## 任务领取与状态
|
||||
|
||||
- Gitea Issue 是实时状态权威,状态标签为 `status/todo`、`status/doing`、`status/blocked`、`status/review`、`status/done`。
|
||||
- Gitea Issue 是实时状态权威,状态标签为 `status/waiting`、`status/todo`、`status/doing`、`status/blocked`、`status/review`、`status/done`;`waiting` 表示尚未领取且因依赖或外部条件不可领取。
|
||||
- 任务文件保存不可变规格、依赖、写路径、验证门禁和执行证据。
|
||||
- 一个 agent 同时最多一个活跃任务;一个任务同时只有一个写入者。
|
||||
- dispatcher 创建 `claims/T-<编号>` 和 `agent/<agent-id>/T-<编号>` 后,worker 必须读回确认。
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
- `docs/raw/01`~`08` 已记录需求、分析、方案、客户场景、事件比对和三系统职责。
|
||||
- `docs/raw/contracts/event-v0.1.schema.json` 已冻结,并有多份示例与语义说明。
|
||||
- harness coding 文档、上下文清单、Gitea Issue/PR 模板和治理脚本已接入。
|
||||
- Gitea 已初始化 11 个协作标签;首批 Issue 已建立,实时可领取状态必须从 Gitea 查询,不在本文复制。
|
||||
- Gitea 已初始化 12 个协作标签;`status/waiting` 用于依赖或外部条件未满足的未领取任务,实时可领取状态必须从 Gitea 查询,不在本文复制。
|
||||
- T-002 已关闭架构影响型问题:首期 S2 民办寄宿学校、客户侧私有部署、ONVIF/RTSP、NVIDIA 主路径、自研 Bell、Web/H5 与客户侧证据存储等边界已批准。
|
||||
- T-004 的 Sense/Bell 单文件交互原型已获产品确认;T-005 已归档 Claude 原稿并补录缺失评审文档,当前定稿与原始依据分开保存。
|
||||
- `_reference/mibeenvr` 为本地只读参考仓库,已被忽略;只允许 M0 实验与白名单借鉴。
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
推荐标签:
|
||||
|
||||
- 类型:`kind/task` 标识可执行任务,并从 `type/docs`、`type/code` 中选择一个主要变更类型。
|
||||
- 状态:`status/todo`、`status/doing`、`status/blocked`、`status/review`、`status/done`。
|
||||
- 状态:`status/waiting`、`status/todo`、`status/doing`、`status/blocked`、`status/review`、`status/done`。
|
||||
- 优先级:`priority/p0`、`priority/p1`、`priority/p2`。
|
||||
|
||||
`status/*`、`type/*`、`priority/*` 分别使用 Gitea exclusive scoped labels,同一分组任一时刻最多一个;`kind/task` 为普通标签。
|
||||
@@ -28,6 +28,7 @@
|
||||
|
||||
| 阶段 | 任务文件 | Issue | 分支 / PR |
|
||||
| --- | --- | --- | --- |
|
||||
| 等待条件 | `TODO` | open + `status/waiting` | 无 claim;依赖或外部条件满足后由 dispatcher 转为 todo |
|
||||
| 待领取 | `TODO` | open + `status/todo` | 无 claim 分支 |
|
||||
| 开发中 | 工作分支上 `DOING` | open + `status/doing` | claim 与工作分支存在 |
|
||||
| 阻塞 | `BLOCKED` | open + `status/blocked` | 默认保留 claim,避免误领 |
|
||||
@@ -40,9 +41,9 @@ Issue 是实时状态权威;默认分支尚未合入工作提交时,其任
|
||||
|
||||
1. 先创建任务文件,写清规格、依赖和初始 `write_paths`,合入默认分支;此时 `issue`、`context_ref`、claim / 工作分支均为 `null`。
|
||||
2. 用 Issue 模板创建唯一主 Issue。新 Issue 只有 `kind/task`,尚未带 `status/todo`。
|
||||
3. 把 Issue 编号回填任务文件,并让 Issue 链接该文件;映射提交合入默认分支后,再选择 `type/*`、`priority/*` 和 `status/todo`。
|
||||
3. 把 Issue 编号回填任务文件,并让 Issue 链接该文件;映射提交合入默认分支后,再选择 `type/*`、`priority/*`。依赖已全部 `DONE` 且未被人工暂缓时使用 `status/todo`,否则使用 `status/waiting`。
|
||||
|
||||
因此 dispatcher 能从默认分支可靠定位任务 ↔ Issue;没有双向映射或没有 `status/todo` 的任务都不可领取。
|
||||
因此 dispatcher 能从默认分支可靠定位任务 ↔ Issue;没有双向映射或不是 `status/todo` 的任务都不可领取。`status/waiting` 不占用 claim,恢复条件必须写在 Issue 评论或任务执行记录中。
|
||||
|
||||
## 串行分配与防重复领取
|
||||
|
||||
|
||||
@@ -26,6 +26,7 @@ from validate_harness_governance import (
|
||||
|
||||
STATUS_LABELS = {
|
||||
"status/todo",
|
||||
"status/waiting",
|
||||
"status/doing",
|
||||
"status/blocked",
|
||||
"status/review",
|
||||
@@ -558,8 +559,8 @@ def audit_repository(
|
||||
findings.append(AuditFinding(number, "stale", "claim 租期不得超过 24 小时。"))
|
||||
if task.lease_until <= now:
|
||||
findings.append(AuditFinding(number, "stale", "claim 已过期,需人工审查回收。"))
|
||||
elif status == "status/todo" and claim_branch in branches:
|
||||
findings.append(AuditFinding(number, "claim", "TODO 仍存在 claim 分支。"))
|
||||
elif status in {"status/todo", "status/waiting"} and claim_branch in branches:
|
||||
findings.append(AuditFinding(number, "claim", "未领取状态仍存在 claim 分支。"))
|
||||
|
||||
matching_prs = [
|
||||
pr
|
||||
|
||||
@@ -38,6 +38,12 @@ LABELS: tuple[dict[str, Any], ...] = (
|
||||
"description": "Ready to claim",
|
||||
"exclusive": True,
|
||||
},
|
||||
{
|
||||
"name": "status/waiting",
|
||||
"color": "D4C5F9",
|
||||
"description": "Not claimable; waiting on dependency or external condition",
|
||||
"exclusive": True,
|
||||
},
|
||||
{
|
||||
"name": "status/doing",
|
||||
"color": "FBCA04",
|
||||
|
||||
@@ -14,6 +14,9 @@ if str(SCRIPTS) not in sys.path:
|
||||
sys.path.insert(0, str(SCRIPTS))
|
||||
|
||||
from audit_gitea_coordination import (
|
||||
ACTIVE_LABELS,
|
||||
READY_OR_ACTIVE_LABELS,
|
||||
STATUS_LABELS,
|
||||
audit_repository,
|
||||
latest_claim,
|
||||
paged,
|
||||
@@ -177,6 +180,11 @@ class OfflineRuleTests(unittest.TestCase):
|
||||
|
||||
|
||||
class GiteaHelperTests(unittest.TestCase):
|
||||
def test_waiting_status_is_not_claimable_or_active(self) -> None:
|
||||
self.assertIn("status/waiting", STATUS_LABELS)
|
||||
self.assertNotIn("status/waiting", READY_OR_ACTIVE_LABELS)
|
||||
self.assertNotIn("status/waiting", ACTIVE_LABELS)
|
||||
|
||||
def test_label_plan_detects_exclusive_change(self) -> None:
|
||||
desired = next(label for label in LABELS if label["name"] == "status/todo")
|
||||
existing = {
|
||||
|
||||
Reference in New Issue
Block a user