@tea-agent/loop-agent 0.28.1 → 0.28.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/AGENTS.md +1 -1
- package/CHANGELOG.md +25 -0
- package/README.md +11 -1
- package/dist/cli/command-definitions.js +2 -1
- package/dist/commands/client-recovery.js +111 -8
- package/dist/commands/dag-init-hybrid.js +1 -1
- package/dist/commands/init-upgrade.js +2479 -0
- package/dist/commands/init.js +120 -9
- package/dist/governance/manifest-types.js +65 -0
- package/dist/shared/operator/capabilities.js +350 -2
- package/dist/task/worktree.js +256 -39
- package/dist/worker/cli.js +22 -12
- package/dist/worker/console/chat/workspace-landing.js +16 -6
- package/dist/worker/console/observe-health-match.js +2 -0
- package/dist/worker/console/observe-link.js +4 -0
- package/dist/worker/console/operator-actions.js +183 -4
- package/dist/worker/console/operator-selection.js +13 -0
- package/dist/worker/console/static/assets/index-BfRgtLF4.js +29 -0
- package/dist/worker/console/static/index.html +1 -1
- package/dist/worker/observe/health.js +1 -0
- package/dist/worker/observe/night-jobs.js +104 -0
- package/dist/worker/observe/routes.js +48 -0
- package/dist/worker/observe/static/app.js +3 -0
- package/dist/worker/observe/static/constants.js +1 -0
- package/dist/worker/observe/static/index.html +47 -0
- package/dist/worker/observe/static/router.js +10 -0
- package/dist/worker/observe/static/shell-chrome.js +1 -0
- package/dist/worker/observe/static/views/night.js +201 -0
- package/dist/worker/report/morning-report.js +56 -16
- package/dist/worker/run-task/execute-prepared-task.js +153 -0
- package/dist/worker/runner/single-task-attempt.js +147 -0
- package/dist/worker/scheduler/admission.js +536 -0
- package/dist/worker/scheduler/auto-followup.js +99 -0
- package/dist/worker/scheduler/cli.js +539 -0
- package/dist/worker/scheduler/dispatcher.js +503 -0
- package/dist/worker/scheduler/doctor.js +346 -0
- package/dist/worker/scheduler/evidence.js +170 -0
- package/dist/worker/scheduler/git-base.js +52 -0
- package/dist/worker/scheduler/index.js +23 -0
- package/dist/worker/scheduler/lease.js +114 -0
- package/dist/worker/scheduler/lifecycle.js +348 -0
- package/dist/worker/scheduler/lock.js +80 -0
- package/dist/worker/scheduler/morning-window.js +161 -0
- package/dist/worker/scheduler/night-git-finalizer.js +88 -0
- package/dist/worker/scheduler/night-harvest.js +421 -0
- package/dist/worker/scheduler/paths.js +84 -0
- package/dist/worker/scheduler/prepared-attempt-recovery.js +471 -0
- package/dist/worker/scheduler/recovery.js +277 -0
- package/dist/worker/scheduler/reservation.js +146 -0
- package/dist/worker/scheduler/retry.js +199 -0
- package/dist/worker/scheduler/scheduler-loop.js +272 -0
- package/dist/worker/scheduler/store.js +275 -0
- package/dist/worker/scheduler/traceability.js +54 -0
- package/dist/worker/scheduler/trigger.js +258 -0
- package/dist/worker/scheduler/types.js +369 -0
- package/dist/worker/scheduler/workspace-adapter.js +91 -0
- package/docs/architecture/runtime-boundaries.md +9 -0
- package/docs/init-surface.manifest.json +9 -2
- package/docs/templates/harness.schema.json +107 -0
- package/docs/templates/init-managed-agents.md +18 -8
- package/harness.json +22 -0
- package/package.json +1 -1
- package/skills/loop-agent/SKILL.md +28 -36
- package/skills/loop-agent/references/command-reference.md +40 -16
- package/skills/loop-agent/references/hybrid-dag.md +1 -1
- package/dist/worker/console/static/assets/index-CNO7n6qB.js +0 -29
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import { access, symlink, unlink } from "node:fs/promises";
|
|
2
|
+
import path from "node:path";
|
|
3
|
+
import { ensureOwnedWorktree, verifyOwnedWorktree, } from "../../task/worktree.js";
|
|
4
|
+
import { getSchedulerRoot } from "./paths.js";
|
|
5
|
+
export function defaultNightWorktreeRelativePath(scheduleId) {
|
|
6
|
+
return path.posix.join(".worktrees", "night", scheduleId);
|
|
7
|
+
}
|
|
8
|
+
export function defaultNightBranch(scheduleId) {
|
|
9
|
+
return `night/${scheduleId}`;
|
|
10
|
+
}
|
|
11
|
+
/**
|
|
12
|
+
* Create or reuse a schedule-owned worktree under control repo.
|
|
13
|
+
* Does not copy secrets/.env. Optional node_modules symlink only.
|
|
14
|
+
*/
|
|
15
|
+
export async function prepareNightWorkspace(spec) {
|
|
16
|
+
const relativeWorktreePath = spec.worktreePath ?? defaultNightWorktreeRelativePath(spec.scheduleId);
|
|
17
|
+
const branch = spec.branch ?? defaultNightBranch(spec.scheduleId);
|
|
18
|
+
const expectedBranch = defaultNightBranch(spec.scheduleId);
|
|
19
|
+
if (branch !== expectedBranch) {
|
|
20
|
+
throw new Error(`night worktree branch must be ${expectedBranch}, got ${branch}`);
|
|
21
|
+
}
|
|
22
|
+
const absolutePath = path.isAbsolute(relativeWorktreePath)
|
|
23
|
+
? relativeWorktreePath
|
|
24
|
+
: path.resolve(spec.controlRepoRoot, relativeWorktreePath);
|
|
25
|
+
// Ensure parent of worktree root exists (and keep scheduler root alive).
|
|
26
|
+
void getSchedulerRoot(spec.controlRepoRoot);
|
|
27
|
+
const ensured = await ensureOwnedWorktree(spec.controlRepoRoot, {
|
|
28
|
+
worktreePath: absolutePath,
|
|
29
|
+
branch,
|
|
30
|
+
baseBranch: spec.baseBranch,
|
|
31
|
+
baseCommit: spec.baseCommit,
|
|
32
|
+
scheduleId: spec.scheduleId,
|
|
33
|
+
...(spec.ownershipToken ? { ownershipToken: spec.ownershipToken } : {}),
|
|
34
|
+
...(spec.now ? { now: spec.now } : {}),
|
|
35
|
+
});
|
|
36
|
+
let nodeModulesLinked = false;
|
|
37
|
+
if (spec.hydrateNodeModules !== false) {
|
|
38
|
+
nodeModulesLinked = await linkNodeModulesIfPresent(spec.controlRepoRoot, ensured.path);
|
|
39
|
+
}
|
|
40
|
+
const relative = path
|
|
41
|
+
.relative(spec.controlRepoRoot, ensured.path)
|
|
42
|
+
.split(path.sep)
|
|
43
|
+
.join("/") || relativeWorktreePath;
|
|
44
|
+
return {
|
|
45
|
+
...ensured,
|
|
46
|
+
relativeWorktreePath: relative.startsWith("..") ? ensured.path : relative,
|
|
47
|
+
relativeBranch: branch,
|
|
48
|
+
nodeModulesLinked,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
export async function revalidateNightWorkspace(input) {
|
|
52
|
+
const result = await verifyOwnedWorktree({
|
|
53
|
+
repoRoot: input.controlRepoRoot,
|
|
54
|
+
worktreePath: input.worktreePath,
|
|
55
|
+
scheduleId: input.scheduleId,
|
|
56
|
+
branch: input.branch,
|
|
57
|
+
baseCommit: input.baseCommit,
|
|
58
|
+
ownershipToken: input.ownershipToken,
|
|
59
|
+
});
|
|
60
|
+
return { head: result.head };
|
|
61
|
+
}
|
|
62
|
+
async function linkNodeModulesIfPresent(controlRepoRoot, worktreePath) {
|
|
63
|
+
const host = path.join(controlRepoRoot, "node_modules");
|
|
64
|
+
const target = path.join(worktreePath, "node_modules");
|
|
65
|
+
try {
|
|
66
|
+
await access(host);
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return false;
|
|
70
|
+
}
|
|
71
|
+
try {
|
|
72
|
+
await access(target);
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// continue to link
|
|
77
|
+
}
|
|
78
|
+
try {
|
|
79
|
+
await symlink(host, target, "junction");
|
|
80
|
+
return true;
|
|
81
|
+
}
|
|
82
|
+
catch {
|
|
83
|
+
try {
|
|
84
|
+
await unlink(target);
|
|
85
|
+
}
|
|
86
|
+
catch {
|
|
87
|
+
// ignore
|
|
88
|
+
}
|
|
89
|
+
return false;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
@@ -12,6 +12,9 @@ Skill layer
|
|
|
12
12
|
CLI layer (src/cli/)
|
|
13
13
|
└─ argv 解析、adapter 解析、调用 application / command handler、格式化输出
|
|
14
14
|
|
|
15
|
+
Init-upgrade command layer (src/commands/init-upgrade.ts)
|
|
16
|
+
└─ controller-owned init-upgrade state machine、frozen identity、target `.harness/init-upgrades/` facts、safe action receipts and bounded merge contracts
|
|
17
|
+
|
|
15
18
|
Application layer (src/application/,逐步引入)
|
|
16
19
|
└─ 一次用户意图的 typed use-case interface,供 CLI、Loop、Workflow 复用
|
|
17
20
|
|
|
@@ -54,6 +57,12 @@ Governance (scripts/check-*.sh, src/governance/)
|
|
|
54
57
|
- **允许依赖**:`src/commands/**`(handler wiring)、`src/adapters/**`、`src/shared/**`、逐步引入的 `src/application/**`。
|
|
55
58
|
- **禁止**:在 router 中维护与 catalog 独立的 command 事实源(Phase 1 整改目标)。
|
|
56
59
|
|
|
60
|
+
### Init-upgrade command boundary
|
|
61
|
+
|
|
62
|
+
- **位置**:`src/commands/init-upgrade.ts`,复用 `src/commands/init.ts` 的 ownership scan / safe action 与 `src/commands/client-recovery.ts` 的 generated recovery builders。
|
|
63
|
+
- **职责**:拥有可恢复升级状态机与目标项目 run facts;version gate、identity drift、active runtime/lock、workspace re-scan、single-file merge boundary、home zero-write fingerprint 和 completion invariant 都由 controller 决定。
|
|
64
|
+
- **禁止**:OpenCode/Pi plugin、主会话 skill 或 notifier 拥有升级状态机;命令不得修改业务源码、用户 home 或以宽泛路径授权模型。主会话仅可按 controller 返回的具体 `allowedPaths` 合并 init surface,随后必须 `--continue`。
|
|
65
|
+
|
|
57
66
|
### Application layer
|
|
58
67
|
|
|
59
68
|
- **位置**:`src/application/**`(按计划逐步引入)
|
|
@@ -56,6 +56,7 @@
|
|
|
56
56
|
"skills/agent-worker/references/agent-worker-operator.md",
|
|
57
57
|
"skills/loop-agent/SKILL.md",
|
|
58
58
|
"skills/loop-agent/references/command-reference.md",
|
|
59
|
+
"skills/loop-agent/references/hybrid-dag.md",
|
|
59
60
|
"skills/loop-agent/references/source-and-plan-practice.md",
|
|
60
61
|
"skills/loop-agent/references/docs-converge.md",
|
|
61
62
|
"skills/ai-engineering-context/SKILL.md",
|
|
@@ -135,6 +136,7 @@
|
|
|
135
136
|
".agents/skills/agent-worker/references/agent-worker-operator.md",
|
|
136
137
|
".agents/skills/loop-agent/SKILL.md",
|
|
137
138
|
".agents/skills/loop-agent/references/command-reference.md",
|
|
139
|
+
".agents/skills/loop-agent/references/hybrid-dag.md",
|
|
138
140
|
".agents/skills/loop-agent/references/source-and-plan-practice.md",
|
|
139
141
|
".agents/skills/loop-agent/references/docs-converge.md",
|
|
140
142
|
".agents/skills/ai-engineering-context/SKILL.md",
|
|
@@ -168,7 +170,8 @@
|
|
|
168
170
|
"docs/templates/backend-test-case-manifest.schema.json",
|
|
169
171
|
".opencode/plugins/loop-agent-transient-retry.js",
|
|
170
172
|
".opencode/plugins/loop-agent-context-overflow-compact.js",
|
|
171
|
-
".pi/extensions/loop-agent-context-overflow.js"
|
|
173
|
+
".pi/extensions/loop-agent-context-overflow.js",
|
|
174
|
+
".pi/settings.json"
|
|
172
175
|
],
|
|
173
176
|
"initSurface": {
|
|
174
177
|
"README.md": "managed-block",
|
|
@@ -218,6 +221,7 @@
|
|
|
218
221
|
".agents/skills/agent-worker/references/agent-worker-operator.md": "copied",
|
|
219
222
|
".agents/skills/loop-agent/SKILL.md": "copied",
|
|
220
223
|
".agents/skills/loop-agent/references/command-reference.md": "copied",
|
|
224
|
+
".agents/skills/loop-agent/references/hybrid-dag.md": "copied",
|
|
221
225
|
".agents/skills/loop-agent/references/source-and-plan-practice.md": "copied",
|
|
222
226
|
".agents/skills/loop-agent/references/docs-converge.md": "copied",
|
|
223
227
|
".agents/skills/ai-engineering-context/SKILL.md": "copied",
|
|
@@ -251,7 +255,8 @@
|
|
|
251
255
|
"docs/templates/backend-test-case-manifest.schema.json": "copied",
|
|
252
256
|
".opencode/plugins/loop-agent-transient-retry.js": "generated",
|
|
253
257
|
".opencode/plugins/loop-agent-context-overflow-compact.js": "generated",
|
|
254
|
-
".pi/extensions/loop-agent-context-overflow.js": "generated"
|
|
258
|
+
".pi/extensions/loop-agent-context-overflow.js": "generated",
|
|
259
|
+
".pi/settings.json": "generated"
|
|
255
260
|
},
|
|
256
261
|
"packageExcluded": [
|
|
257
262
|
"docs/progress/20*.md",
|
|
@@ -273,6 +278,7 @@
|
|
|
273
278
|
"package.json",
|
|
274
279
|
"src/commands/init.ts",
|
|
275
280
|
"src/commands/client-recovery.ts",
|
|
281
|
+
"src/commands/init-upgrade.ts",
|
|
276
282
|
"src/cli.ts",
|
|
277
283
|
"src/cli/update/init-surface-notifier.ts",
|
|
278
284
|
"src/cli/update/policy.ts",
|
|
@@ -297,6 +303,7 @@
|
|
|
297
303
|
"patterns": [
|
|
298
304
|
"src/commands/init.ts",
|
|
299
305
|
"src/commands/client-recovery.ts",
|
|
306
|
+
"src/commands/init-upgrade.ts",
|
|
300
307
|
"src/cli.ts",
|
|
301
308
|
"src/cli/update/init-surface-notifier.ts",
|
|
302
309
|
"src/cli/update/policy.ts",
|
|
@@ -111,6 +111,113 @@
|
|
|
111
111
|
}
|
|
112
112
|
}
|
|
113
113
|
},
|
|
114
|
+
"workerPolicy": {
|
|
115
|
+
"type": "object",
|
|
116
|
+
"additionalProperties": false,
|
|
117
|
+
"description": "agent-worker 侧声明式策略(含 Night Scheduler)。运行时以 Zod harnessManifestSchema 为准。",
|
|
118
|
+
"properties": {
|
|
119
|
+
"nightScheduler": {
|
|
120
|
+
"type": "object",
|
|
121
|
+
"additionalProperties": false,
|
|
122
|
+
"description": "本地夜间 once 调度默认策略;每个 schedule 会冻结 effective snapshot。",
|
|
123
|
+
"properties": {
|
|
124
|
+
"enabled": {
|
|
125
|
+
"type": "boolean",
|
|
126
|
+
"description": "是否启用 Night Scheduler 能力面。",
|
|
127
|
+
"default": false
|
|
128
|
+
},
|
|
129
|
+
"timezone": {
|
|
130
|
+
"type": "string",
|
|
131
|
+
"minLength": 1,
|
|
132
|
+
"description": "展示与 allowedHours 解释使用的 IANA 时区。",
|
|
133
|
+
"default": "Asia/Shanghai"
|
|
134
|
+
},
|
|
135
|
+
"allowedHours": {
|
|
136
|
+
"type": "array",
|
|
137
|
+
"description": "允许派发的本地时间窗,格式 HH:MM-HH:MM,可跨午夜。",
|
|
138
|
+
"items": {
|
|
139
|
+
"type": "string",
|
|
140
|
+
"pattern": "^\\d{2}:\\d{2}-\\d{2}:\\d{2}$"
|
|
141
|
+
},
|
|
142
|
+
"default": ["00:00-08:00"]
|
|
143
|
+
},
|
|
144
|
+
"maxConcurrency": {
|
|
145
|
+
"type": "integer",
|
|
146
|
+
"minimum": 1,
|
|
147
|
+
"description": "全局同时 running 的 schedule 上限(按有效 execution lease 计数)。",
|
|
148
|
+
"default": 1
|
|
149
|
+
},
|
|
150
|
+
"maxAutoAttempts": {
|
|
151
|
+
"type": "integer",
|
|
152
|
+
"minimum": 1,
|
|
153
|
+
"description": "独立 Worker execution attempt 上限;MVP 为 1。",
|
|
154
|
+
"default": 1
|
|
155
|
+
},
|
|
156
|
+
"misfirePolicy": {
|
|
157
|
+
"enum": ["run-immediately", "wait-next-window", "human-required"],
|
|
158
|
+
"description": "机器休眠或 tick 延迟后的 misfire 策略。",
|
|
159
|
+
"default": "wait-next-window"
|
|
160
|
+
},
|
|
161
|
+
"keepFailedWorktree": {
|
|
162
|
+
"type": "boolean",
|
|
163
|
+
"description": "失败后是否默认保留 worktree 供人工 inspect。",
|
|
164
|
+
"default": true
|
|
165
|
+
},
|
|
166
|
+
"mergePolicy": {
|
|
167
|
+
"enum": ["manual-on-success", "auto-on-success"],
|
|
168
|
+
"description": "成功后的 merge 策略;MVP 仅 manual-on-success。",
|
|
169
|
+
"default": "manual-on-success"
|
|
170
|
+
},
|
|
171
|
+
"autoFollowUp": {
|
|
172
|
+
"type": "object",
|
|
173
|
+
"additionalProperties": false,
|
|
174
|
+
"description": "ADR 0010:失败后是否自动 draft Follow-up(永不 auto-approve)。默认 off。",
|
|
175
|
+
"properties": {
|
|
176
|
+
"enabled": {
|
|
177
|
+
"type": "boolean",
|
|
178
|
+
"description": "为 true 时,terminal failed night execution 可调用 draftFollowUpDecision。",
|
|
179
|
+
"default": false
|
|
180
|
+
},
|
|
181
|
+
"mode": {
|
|
182
|
+
"enum": ["draft-only"],
|
|
183
|
+
"description": "MVP 仅 draft-only;自动 Ready/approve 需另 ADR。",
|
|
184
|
+
"default": "draft-only"
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
},
|
|
188
|
+
"traceability": {
|
|
189
|
+
"type": "object",
|
|
190
|
+
"additionalProperties": false,
|
|
191
|
+
"description": "可 push commit 的工作项可追溯策略(任务卡片)。",
|
|
192
|
+
"properties": {
|
|
193
|
+
"required": {
|
|
194
|
+
"type": "boolean",
|
|
195
|
+
"description": "创建 schedule 时是否强制任务卡片。",
|
|
196
|
+
"default": false
|
|
197
|
+
},
|
|
198
|
+
"label": {
|
|
199
|
+
"type": "string",
|
|
200
|
+
"minLength": 1,
|
|
201
|
+
"default": "Task Card"
|
|
202
|
+
},
|
|
203
|
+
"pattern": {
|
|
204
|
+
"type": "string",
|
|
205
|
+
"minLength": 1,
|
|
206
|
+
"description": "workItemRef 正则;默认通用公司卡片格式。",
|
|
207
|
+
"default": "^[A-Z][A-Z0-9]+-[A-Z0-9]+#[0-9]+$"
|
|
208
|
+
},
|
|
209
|
+
"commitMessageTemplate": {
|
|
210
|
+
"type": "string",
|
|
211
|
+
"minLength": 1,
|
|
212
|
+
"description": "必须包含 {workItemRef} 占位符。",
|
|
213
|
+
"default": "{summary}\n\n{workItemRef}"
|
|
214
|
+
}
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
}
|
|
219
|
+
}
|
|
220
|
+
},
|
|
114
221
|
"entrypoints": {
|
|
115
222
|
"type": "object",
|
|
116
223
|
"description": "具名的仓库相对文件路径,用作人类和 agent 的入口。",
|
|
@@ -42,24 +42,34 @@
|
|
|
42
42
|
| 用户表达 | 入口 | 执行动作 |
|
|
43
43
|
| --- | --- | --- |
|
|
44
44
|
| loop-agent 初始化 / loop agent 初始化 / loop agent初始化 / 初始化 loop-agent | 初始化 | 完成确定性初始化闭环 |
|
|
45
|
-
|
|
|
46
|
-
|
|
|
47
|
-
|
|
|
45
|
+
| loop-agent初始化更新 / loop-agent 初始化更新 / 更新 loop-agent 初始化内容 / 升级 loop-agent 初始化 | 初始化升级闭环 | 直接运行 `init upgrade`;自动安全更新、返回单文件语义合并任务并 `--continue` 至稳定终态,禁止停在只读检查或 `needs-model-merge` |
|
|
46
|
+
| 初始化更新校验 / 检查初始化更新 / loop-agent 初始化更新校验 / loop agent初始化更新校验 / 只检查,不要修改 | 更新校验 | 严格只读报告,不创建 upgrade run、不写入 |
|
|
47
|
+
| 初始化对齐 / 升级后对齐 / reconcile 初始化 / loop-agent 初始化对齐 | 初始化升级闭环 | 直接运行 `init upgrade`,而非拼接低层 safe-update 命令 |
|
|
48
|
+
| 初始化安全更新 / 应用初始化更新 / loop-agent 初始化安全更新 / loop agent初始化安全更新 | 初始化升级闭环 | 直接运行 `init upgrade`,由 controller 处理安全更新与验证 |
|
|
48
49
|
| loop-agent 帮我完成 / 帮我实现 / 帮我修复 / 帮我开发 <需求>;使用 loop-agent 完成 <X>;按 loop-agent 流程处理 <X> | 通用需求实现 | 先提供 PRD 与 `allowedPaths` / `forbiddenPaths` / verify,再 `task advance` → 审查 writeSet gate → `task advance --approve-gate`;主会话不得直接修改业务实现 |
|
|
49
50
|
|
|
50
|
-
|
|
51
|
+
**初始化升级闭环(写入型)**:主会话收到上述写入型表达时自动调用统一入口,并在 controller 返回的具体单文件 `allowedPaths` 内完成必要语义合并后使用 `--continue`。不得停在 `check-update`、`needs-safe-update`、`needs-model-merge` 或 `verification-pending`。默认安装/合并项目 `.opencode/plugins/`、`.pi/extensions/` 与 `.pi/settings.json`;Pi 必须 trust 项目才能加载,默认严禁写 `~/.pi/agent/settings.json`。
|
|
51
52
|
|
|
52
53
|
```bash
|
|
53
|
-
loop-agent init
|
|
54
|
+
loop-agent init upgrade --repo-root . --json
|
|
55
|
+
loop-agent init upgrade --repo-root . --run-id <run-id> --continue --json
|
|
56
|
+
loop-agent init upgrade --repo-root . --run-id <run-id> --report --markdown
|
|
54
57
|
```
|
|
55
58
|
|
|
56
|
-
|
|
59
|
+
**更新校验(只读)**:只读执行下面命令;**不得自动**执行 `apply-safe`、模型合并或创建 upgrade run。
|
|
60
|
+
|
|
61
|
+
```bash
|
|
62
|
+
loop-agent init check-update --repo-root . --markdown
|
|
63
|
+
```
|
|
57
64
|
|
|
58
|
-
|
|
65
|
+
**低层兼容命令(仅诊断/恢复,不是自然语言写入入口)**:`init reconcile`、`init update --bootstrap-surface` 与 `init update --apply-safe` 保留给 controller 诊断、旧自动化和人工排障。主会话收到任何写入型“初始化更新 / 初始化对齐 / 安全更新”表达时,必须唯一进入 `init upgrade`,不得改为直接调用这些低层命令,也不得在它们返回 `needs-model-merge` 后停止。surface 缺失、human decisions、活跃 DAG/Worker 或 Worker 状态无法确认时仍必须零写入。
|
|
59
66
|
|
|
60
67
|
```bash
|
|
68
|
+
# 只读诊断
|
|
61
69
|
loop-agent init check-update --repo-root . --markdown
|
|
62
|
-
|
|
70
|
+
# 低层兼容恢复;不得替代写入型自然语言的统一 init upgrade 入口
|
|
71
|
+
loop-agent init reconcile --repo-root .
|
|
72
|
+
loop-agent init update --repo-root . --bootstrap-surface
|
|
63
73
|
loop-agent init update --repo-root . --apply-safe
|
|
64
74
|
```
|
|
65
75
|
|
package/harness.json
CHANGED
|
@@ -26,6 +26,28 @@
|
|
|
26
26
|
]
|
|
27
27
|
}
|
|
28
28
|
},
|
|
29
|
+
"workerPolicy": {
|
|
30
|
+
"nightScheduler": {
|
|
31
|
+
"enabled": true,
|
|
32
|
+
"timezone": "Asia/Shanghai",
|
|
33
|
+
"allowedHours": ["00:00-08:00"],
|
|
34
|
+
"maxConcurrency": 1,
|
|
35
|
+
"maxAutoAttempts": 1,
|
|
36
|
+
"misfirePolicy": "wait-next-window",
|
|
37
|
+
"keepFailedWorktree": true,
|
|
38
|
+
"mergePolicy": "manual-on-success",
|
|
39
|
+
"autoFollowUp": {
|
|
40
|
+
"enabled": false,
|
|
41
|
+
"mode": "draft-only"
|
|
42
|
+
},
|
|
43
|
+
"traceability": {
|
|
44
|
+
"required": true,
|
|
45
|
+
"label": "Task Card",
|
|
46
|
+
"pattern": "^[A-Z][A-Z0-9]+-[A-Z0-9]+#[0-9]+$",
|
|
47
|
+
"commitMessageTemplate": "{summary}\n\n{workItemRef}"
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
},
|
|
29
51
|
"entrypoints": {
|
|
30
52
|
"readme": "README.md",
|
|
31
53
|
"agents": "AGENTS.md",
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: loop-agent
|
|
3
3
|
description: >-
|
|
4
|
-
Use when implementing features, processing PRDs or requirements, running structured loop-agent workflows, creating harness tasks, using Agent DAG / task advance lifecycle, pi-prompt planning/review, cursor-prompt one-shot sidecar intervention, initializing a target project with loop-agent, checking init update status, applying a safe init update, or converging website/governance docs after user-visible changes in loop-agent. Triggers: loop-agent, workflow, structured development, harness task, Agent DAG, task advance, task status, dag validate, dag execute, docs converge, Converge Docs, 文档收敛, 结构化开发, 工作流, 需求实现, PRD 实现, 初始化 loop-agent, loop agent 初始化, loop agent初始化, loop-agent 初始化, 初始化更新校验, loop agent初始化更新校验, 检查初始化更新, 初始化安全更新, loop agent初始化安全更新,
|
|
4
|
+
Use when implementing features, processing PRDs or requirements, running structured loop-agent workflows, creating harness tasks, using Agent DAG / task advance lifecycle, pi-prompt planning/review, cursor-prompt one-shot sidecar intervention, initializing a target project with loop-agent, checking init update status, applying a safe init update, or converging website/governance docs after user-visible changes in loop-agent. Triggers: loop-agent, workflow, structured development, harness task, Agent DAG, task advance, task status, dag validate, dag execute, docs converge, Converge Docs, 文档收敛, 结构化开发, 工作流, 需求实现, PRD 实现, 初始化 loop-agent, loop agent 初始化, loop agent初始化, loop-agent 初始化, 初始化更新校验, loop agent初始化更新校验, 检查初始化更新, 初始化安全更新, loop agent初始化安全更新, 应用初始化更新, loop-agent初始化更新, loop-agent 初始化更新, 更新 loop-agent 初始化内容, 升级后对齐. 强路由:loop-agent 帮我完成需求, 帮我实现, 帮我修复, 帮我开发, 使用 loop-agent 完成, 按 loop-agent 流程处理, 通用需求实现;这些表达确定性地进入 task advance / Agent DAG CLI,主会话编排而不直接写业务实现.
|
|
5
5
|
references:
|
|
6
6
|
- path: references/harness-policy.md
|
|
7
7
|
required: true
|
|
@@ -13,61 +13,53 @@ references:
|
|
|
13
13
|
|
|
14
14
|
# loop-agent Workflow
|
|
15
15
|
|
|
16
|
-
|
|
16
|
+
入口只保留路由与硬约束;细节由 frontmatter required references 注入,`command-reference.md` 保持可选。
|
|
17
17
|
|
|
18
18
|
## 默认立场
|
|
19
19
|
|
|
20
|
-
- 主入口是 **Agent DAG
|
|
21
|
-
-
|
|
22
|
-
-
|
|
23
|
-
- DAG `pi` executor 默认 read-only;`toolProfile: "write"` 时为 bounded writer;sidecar 须 per call 收窄。
|
|
24
|
-
- Shell verification 是事实源;长期结论写回 `ai_workspace/loop-agent/`、`docs/decisions/` 或 `skills/`。
|
|
20
|
+
- 主入口是 **Agent DAG**;主会话只编排 CLI、审 writeSet、处理 gate、验证与 handoff,不写业务实现。
|
|
21
|
+
- 禁止绕过 CLI 用宿主 Edit/Write「救火」;失败走 doctor/reconcile/human gate/重跑。
|
|
22
|
+
- `pi` 默认 read-only;仅 `toolProfile: "write"` 是 bounded writer。Shell verification 是事实源。
|
|
25
23
|
|
|
26
|
-
##
|
|
24
|
+
## 初始化升级路由
|
|
27
25
|
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
--prd <prd.md> \
|
|
32
|
-
--allowed-path "<glob>" \
|
|
33
|
-
--forbidden-path ".harness/**" \
|
|
34
|
-
--verify "typecheck:npm run typecheck" \
|
|
35
|
-
--json
|
|
26
|
+
- 写入型「**loop-agent初始化更新**」「loop-agent 初始化更新」「更新 loop-agent 初始化内容」「升级后对齐」统一运行 `loop-agent init upgrade --repo-root . --json`;处理 controller 返回的单文件 `allowedPaths`,以同一 run `--continue` 推进至终态,不停在中间状态。
|
|
27
|
+
- 「检查初始化更新」「初始化更新校验」「只检查,不要修改」仅运行 `loop-agent init check-update --repo-root . --markdown`,不得创建 run 或写入。
|
|
28
|
+
- facts 位于 `.harness/init-upgrades/<run-id>/`;禁止业务源码和宽泛 glob。默认管理项目 `.opencode/plugins/`、`.pi/extensions/`、`.pi/settings.json`;Pi trust 后加载,默认不读写 `~/.pi/agent/settings.json`。
|
|
36
29
|
|
|
37
|
-
|
|
38
|
-
loop-agent task advance <task-id> \
|
|
39
|
-
--approve-gate "write-set-review:<digest>" \
|
|
40
|
-
--json
|
|
30
|
+
## 标准路径
|
|
41
31
|
|
|
42
|
-
|
|
32
|
+
```bash
|
|
33
|
+
loop-agent task advance <task-id> "Title" --prd <prd.md> \
|
|
34
|
+
--allowed-path "<glob>" --forbidden-path ".harness/**" \
|
|
35
|
+
--verify "typecheck:npm run typecheck" --json
|
|
36
|
+
loop-agent task advance <task-id> \
|
|
37
|
+
--approve-gate "write-set-review:<digest>" --json
|
|
43
38
|
loop-agent task status <task-id> --json
|
|
44
39
|
```
|
|
45
40
|
|
|
46
|
-
|
|
41
|
+
非微小跨会话任务可先 `plan create`。主会话只审 gate/writeSet 与验证证据,不拼低层 prepare/run-task/run-dag/promote/closeout 命令串。
|
|
47
42
|
|
|
48
|
-
##
|
|
43
|
+
## 主题路由
|
|
49
44
|
|
|
50
45
|
| 主题 | Reference |
|
|
51
46
|
| --- | --- |
|
|
52
47
|
| Harness policy、Loop、SePO-lite | `references/harness-policy.md` |
|
|
53
|
-
|
|
|
48
|
+
| DAG topology、writeSet、recovery | `references/hybrid-dag.md` |
|
|
54
49
|
| Operator commands、`agent-worker` | `references/command-reference.md` |
|
|
55
|
-
|
|
|
50
|
+
| 验证、failure、closeout | `references/verification-and-failure-handling.md` |
|
|
56
51
|
|
|
57
52
|
## Hard Rules
|
|
58
53
|
|
|
59
54
|
1. Use vertical tracer bullets across real integration layers;each needs independent acceptance and verification.
|
|
60
|
-
2. Autonomy ≠ governance profile
|
|
61
|
-
3.
|
|
62
|
-
4.
|
|
63
|
-
5. Agent DAG
|
|
64
|
-
6.
|
|
65
|
-
7.
|
|
66
|
-
8.
|
|
67
|
-
9. Client recovery:`init --client-recovery=auto|project|user|off` 投影 transient-retry + overflow-compact + Pi overflow extension;只有 `user` 写 Pi settings;overflow 与 transient 职责分离;check/update 遵守 ownership。
|
|
55
|
+
2. Autonomy ≠ governance profile;AFK/HITL 属 human gate,`--profile` 按风险选择。
|
|
56
|
+
3. 必须读取 `source/需求.md`、`source/执行约束.md`,优先原始 `source/references/*`。
|
|
57
|
+
4. `referenceDocs` uses `{ path, name? }[]`, never a string array;`verifyCommands` uses `{ label, command, timeoutMs? }[]`, never a string array。
|
|
58
|
+
5. Agent DAG 才是实现流;review 三向核对 references、derived source、implementation。
|
|
59
|
+
6. read-only DAG/sidecar 不得写 root `artifacts/`;completed run facts 只读。
|
|
60
|
+
7. 关键状态不得只留在聊天;完成前必须验证。
|
|
61
|
+
8. Client recovery 的 `auto|project|user|off` 遵守 ownership;仅 `user` 写用户 Pi settings,overflow 与 transient 分工。
|
|
68
62
|
|
|
69
63
|
## References
|
|
70
64
|
|
|
71
|
-
Required
|
|
72
|
-
|
|
73
|
-
Optional 索引见 `references/README.md`;常用:`command-reference.md`、`long-running-loop.md`、`orchestrator-and-interventions.md`、`docs-converge.md`。
|
|
65
|
+
Required:`references/harness-policy.md`、`references/hybrid-dag.md`、`references/verification-and-failure-handling.md`。Optional 见 `references/README.md`;常用 `references/command-reference.md`、`references/source-and-plan-practice.md`、`references/long-running-loop.md`、`references/orchestrator-and-interventions.md`、`references/docs-converge.md`。
|
|
@@ -36,18 +36,23 @@ loop-agent doctor
|
|
|
36
36
|
1. **主路径 lifecycle**,用于常规 autonomous work:
|
|
37
37
|
|
|
38
38
|
```bash
|
|
39
|
-
# 非微小 / 跨会话(推荐默认):loop-agent plan create
|
|
40
|
-
loop-agent task advance
|
|
41
|
-
--prd
|
|
42
|
-
--accept-recommendations
|
|
43
|
-
|
|
39
|
+
# 非微小 / 跨会话(推荐默认):loop-agent plan create PLAN_ID "Title"
|
|
40
|
+
loop-agent task advance TASK_ID "Task Title" \
|
|
41
|
+
--prd path/to/prd.md \
|
|
42
|
+
--accept-recommendations DIGEST \
|
|
43
|
+
--allowed-path "src/**" \
|
|
44
44
|
--forbidden-path ".harness/**" \
|
|
45
45
|
--verify "typecheck:npm run typecheck" \
|
|
46
46
|
--json
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
loop-agent task
|
|
50
|
-
|
|
47
|
+
|
|
48
|
+
# 审查 gate.writeSet / gate.digest 后
|
|
49
|
+
loop-agent task advance TASK_ID \
|
|
50
|
+
--approve-gate "write-set-review:DIGEST" \
|
|
51
|
+
--json
|
|
52
|
+
loop-agent task status TASK_ID --json
|
|
53
|
+
|
|
54
|
+
# 有 plan 时收尾
|
|
55
|
+
loop-agent plan complete PLAN_ID --summary "..."
|
|
51
56
|
```
|
|
52
57
|
|
|
53
58
|
首次 `task advance` 内部完成 create、PRD 归档、managed contract 投影、DAG 生成与 strict validate,并停在 writeSet gate;批准后同一命令长跑到稳定终态并做确定性 promotion/closeout。决策表与反模式见 `source-and-plan-practice.md`。
|
|
@@ -115,9 +120,10 @@ SDK 回归或 SDK 可选依赖不可用时用 `cli-only` 诊断。CLI fallback
|
|
|
115
120
|
| 用户表达 | 命令 |
|
|
116
121
|
| --- | --- |
|
|
117
122
|
| loop-agent 初始化 / loop agent 初始化 / loop agent初始化 / 初始化 loop-agent | 先运行 `loop-agent init instructions --repo-root .`,再运行 `loop-agent init --repo-root . --profile full --merge`,随后补全 README/验证矩阵并复查 doctor/inspect/docs audit |
|
|
118
|
-
|
|
|
119
|
-
|
|
|
120
|
-
|
|
|
123
|
+
| loop-agent初始化更新 / loop-agent 初始化更新 / 更新 loop-agent 初始化内容 / 升级 loop-agent 初始化 / 初始化对齐 / 升级后对齐 | `loop-agent init upgrade --repo-root . --json`(写入型 controller-owned 闭环;主会话完成 controller 返回的具体单文件 merge task 后以 `--continue` 推进,禁止停在中间态) |
|
|
124
|
+
| 初始化更新校验 / loop agent初始化更新校验 / 检查初始化更新 / 只检查,不要修改 | `loop-agent init check-update --repo-root . --markdown`(严格只读;不得创建 upgrade run、`apply-safe` 或模型合并) |
|
|
125
|
+
| 初始化安全更新 / loop agent初始化安全更新 / 应用初始化更新 | `loop-agent init upgrade --repo-root . --json`(不要求用户拼接低层安全更新参数) |
|
|
126
|
+
| init reconcile / 控制器升级后对齐目标项目 | `loop-agent init upgrade --repo-root . --json`(保留 `reconcile` 仅作兼容低层诊断) |
|
|
121
127
|
| loop-agent 帮我完成 / 帮我实现 / 帮我修复 / 帮我开发 <需求>;使用 loop-agent 完成 <X>;按 loop-agent 流程处理 <X> | 先 `loop-agent task advance <task-id> "任务标题" --prd <prd.md> --allowed-path "<glob>" --json`,审查 writeSet gate 后 `task advance --approve-gate write-set-review:<digest> --json`;主会话编排而不直接写业务实现 |
|
|
122
128
|
|
|
123
129
|
```bash
|
|
@@ -128,14 +134,18 @@ loop-agent init check-update --repo-root <target-repo> --json
|
|
|
128
134
|
loop-agent init check-update --repo-root <target-repo> --markdown
|
|
129
135
|
loop-agent init update --repo-root <target-repo> --bootstrap-surface
|
|
130
136
|
loop-agent init update --repo-root <target-repo> --apply-safe
|
|
131
|
-
loop-agent init reconcile --repo-root <target-repo> [--json|--markdown]
|
|
137
|
+
loop-agent init reconcile --repo-root <target-repo> [--json|--markdown] # compatibility low-level diagnostic
|
|
138
|
+
loop-agent init upgrade --repo-root <target-repo> --json
|
|
139
|
+
loop-agent init upgrade --repo-root <target-repo> --run-id <run-id> --status --json
|
|
140
|
+
loop-agent init upgrade --repo-root <target-repo> --run-id <run-id> --continue --json
|
|
141
|
+
loop-agent init upgrade --repo-root <target-repo> --run-id <run-id> --report --markdown
|
|
132
142
|
```
|
|
133
143
|
|
|
134
144
|
`init check-update` 是只读升级报告,用于发现目标项目是否落后于当前包内初始化 surface。输出会区分 deterministic actions、model merge tasks、human decisions 和 recommended next。`--markdown` 会渲染可直接交给模型执行的合并指引,包含 `allowedPaths`、`forbiddenPaths`、`mergeRules` 和 `verification`。
|
|
135
145
|
|
|
136
146
|
`init update --bootstrap-surface` 为旧项目写入 `.harness/init-surface.json` 的 `inferred-baseline`,不伪装成历史 recorded baseline。`init update --apply-safe` 只执行确定性安全动作:补缺失文件、创建目录、刷新 managed block;已有但无法确认与当前包一致的文件会进入 model merge tasks,不会被覆盖。
|
|
137
147
|
|
|
138
|
-
`init
|
|
148
|
+
`init upgrade` 是写入型升级入口:首次运行冻结 controller identity、检查 npm latest、扫描 surface、自动执行安全动作,并把 run facts 持久化到 `.harness/init-upgrades/<run-id>/`。`--status` 与 `--report` 严格只读;`--continue` 会重新核验 identity、当前 hash 与不变量。版本选择、无法判定冲突、凭据、破坏性删除或 active writer 才进入 human decision。普通语义冲突返回具体单文件 `allowedPaths` merge task,主会话必须合并后继续,不能把 `needs-model-merge` 作为完成。默认管理项目级 OpenCode/Pi recovery 与 `.pi/settings.json` nested merge,保留显式 disabled,Pi trust 后才加载;默认不读写 `~/.pi/agent/settings.json`。旧 `init reconcile` 保留为兼容低层诊断。
|
|
139
149
|
|
|
140
150
|
### 查看或复制内置示例
|
|
141
151
|
|
|
@@ -541,7 +551,20 @@ agent-worker batch run-ready \
|
|
|
541
551
|
[--check-repo] [--check-repo-command <command...>] \
|
|
542
552
|
[--quiet] \
|
|
543
553
|
[--pi-model <model>] # smoke 覆盖:所有 pi 节点强制用该模型
|
|
544
|
-
agent-worker report morning --repo <repo-root> [--batch-run-id <id>] [--output <path>]
|
|
554
|
+
agent-worker report morning --repo <repo-root> [--batch-run-id <id>] [--output <path>] [--window night] [--date YYYY-MM-DD] [--tz Asia/Shanghai]
|
|
555
|
+
agent-worker admission prepare --repo <repo-root> --feature-dir <path> --task-id <id> --at "YYYY-MM-DD HH:mm" [--tz Asia/Shanghai] [--task-card <ref>] [--json]
|
|
556
|
+
agent-worker admission show <schedule-id> --repo <repo-root> [--json]
|
|
557
|
+
agent-worker scheduler list --repo <repo-root> [--json]
|
|
558
|
+
agent-worker scheduler status <schedule-id> --repo <repo-root> [--json]
|
|
559
|
+
agent-worker scheduler ledger <schedule-id> --repo <repo-root> [--json]
|
|
560
|
+
agent-worker scheduler doctor --repo <repo-root> [--json]
|
|
561
|
+
agent-worker scheduler add <schedule-id> --repo <repo-root> --approve-gate <token> [--json]
|
|
562
|
+
agent-worker scheduler cancel <schedule-id> --repo <repo-root> [--reason <text>] [--json]
|
|
563
|
+
agent-worker scheduler harvest <schedule-id> --repo <repo-root> [--json]
|
|
564
|
+
agent-worker scheduler discard <schedule-id> --repo <repo-root> --reason <text> [--force] [--json]
|
|
565
|
+
agent-worker scheduler tick --repo <repo-root> [--json] # daemon/clock; not Operator Chat
|
|
566
|
+
agent-worker scheduler submit --repo <repo-root> --feature-id <id> --task-id <id> ... # low-level planning fact
|
|
567
|
+
agent-worker scheduler transition <schedule-id> --repo <repo-root> --to <status> ... # internal lifecycle
|
|
545
568
|
agent-worker console [--repo <repo-root>] [--port 8790] [--host 127.0.0.1] # Official 裸入口;repo 默认当前目录
|
|
546
569
|
agent-worker console serve --repo <repo-root> [--port 8790] [--host 127.0.0.1] # 兼容入口,等价于裸入口
|
|
547
570
|
agent-worker console doctor --repo <repo-root> [--json] [--console-url <url>]
|
|
@@ -570,7 +593,8 @@ agent-worker observe snapshot --repo <repo-root> # 输出 GlobalSnapshot JSON
|
|
|
570
593
|
- `task draft-followup` 会按全部 failure category 生成 TaskDraft 或人工行动卡:ProductBug/TestBug/FlakyTest/DependencyFailure 可批准;EnvFailure 连续两次后才生成 ENV-CHECK;Spec/Contract/Risk/Human/Unknown 只给行动卡。人工以 `feature approve-followup --dry-run` 预览,再带非空 `--owner` 批准 TaskDraft;行动卡不能批准。批准在 staging validation 后写 TaskSpec、graph、Ready/approval/event,原失败事实不改写,并有 rename/state/approval/index/event 回滚门禁。
|
|
571
594
|
- `task retry` 是失败 Task 的唯一重试入口。它会保留原有运行记录和 failure handoff,并让下一次 `batch run-ready` 使用新的 `workerRunId`;不要删除运行态文件或手动修改状态来重试。
|
|
572
595
|
- **推荐**裸入口 `agent-worker console`(repo 默认当前目录,默认 `127.0.0.1:8790`)提供 Operate + Inspect;`console serve` 是等价兼容入口。Inspect 路径为 `/inspect/#/...`,API 仍为根 `/api/**`。`observe serve` 为兼容入口(默认 `8787`,启动时 stderr 输出 `OBSERVE_SERVE_DEPRECATED`);`observe snapshot` 保留。Inspect/Observe 本身不会启动、暂停或重试 Task / Worker / DAG。
|
|
573
|
-
-
|
|
596
|
+
- Night Scheduler(本地夜间自治):白天 `admission prepare` 冻结 worktree + DAG writeSet gate;`scheduler add` 消费 gate 并预约 Task Pool `Queued`(不立即执行);`scheduler tick` 作为 Worker 时钟 claim/dispatch(CLI/cron,不进 Operator Chat);成功后 `pending-harvest`,早晨 `scheduler harvest`(exact-base FF)或 `scheduler discard`;`report morning --window night` 与 Inspect `#/night` / Operate 夜间面板读取同一套 facts。
|
|
597
|
+
- 当前 Worker 仍是 v0(库 + CLI + dogfood);日间批处理未强制定时/CI 驱动;`report morning` 默认可从 Task Pool runs 汇总,并支持 `--window night` 投影 Scheduler facts。
|
|
574
598
|
|
|
575
599
|
### 查看 duration statistics / context usage
|
|
576
600
|
|
|
@@ -65,7 +65,7 @@ loop-agent dag execute --dag <temp-dir>/hybrid-dag.json --init-only --canvas-pat
|
|
|
65
65
|
|
|
66
66
|
**运维 warning**:
|
|
67
67
|
|
|
68
|
-
- **常规 validation**:`dag validate --dag <path>` 做 schema/topology/ranks。JSON 输出含 `governanceProfile`(确定性 `minimal|standard|reviewed|supervised` 推断,含 `process` / `delivery` / `codeChange` signal 与 `reasons`),及 model-matrix drift、governance lint(如 read-only artifact-boundary drift 或 DAG 内 `check-repo.sh` shell env drift)的 warnings。手写临时 DAG spec 执行前用 `dag validate --dag <path> --strict-models`;governance warning 应 fail fast 时加 `--strict-governance`。含 `executor: "cursor"` 的旧 DAG 会在 schema 校验失败;默认生成 DAG 使用 `pi` read-only / Pi write profile / shell
|
|
68
|
+
- **常规 validation**:`dag validate --dag <path>` 做 schema/topology/ranks。JSON 输出含 `governanceProfile`(确定性 `minimal|standard|reviewed|supervised` 推断,含 `process` / `delivery` / `codeChange` signal 与 `reasons`),及 model-matrix drift、governance lint(如 read-only artifact-boundary drift 或 DAG 内 `check-repo.sh` shell env drift)的 warnings。手写临时 DAG spec 执行前用 `dag validate --dag <path> --strict-models`;governance warning 应 fail fast 时加 `--strict-governance`。含 `executor: "cursor"` 的旧 DAG 会在 schema 校验失败;默认生成 DAG 使用 `pi` read-only / Pi write profile / shell。`dag execute --dry-run` 仅用于需要预演的场景:snapshot 位于命令返回的 `.harness/dag-runs/dry-run/<runId>/` `runDir`,不创建 active run、不进入 active overview,也不可作为 `dag resume` 目标。
|
|
69
69
|
- **Governance profile 推断与 routing(code vs skill 分工)**:`./src/workflows/dag/governance-profile.ts` 从 DAG 结构与 write scope 做 **硬确定性推断**。JSON 输出 **报告** `process` / `delivery` / `codeChange` signal 与人类可读 `reasons`;`profile` tier(`minimal|standard|reviewed|supervised`)仅由该模块 code rule 选择(如多个 exclusive writer、repair node、review-gate topology、`loop-agent-runtime-paths`、`scripts-ci-harness-paths`、weak post-implementation shell verification、supervised topology)。baseline `forbiddenPaths`(`.harness/**`、`.harness/dag-runs/**`、`artifacts/**`)是默认 governance,**本身不是** process-risk signal。skill prompt 与本 reference **解释** tier 并摘要 profile 选择原因;不替代 code 推断。`task advance` 转发 embedded validate step 的同一 candidate `governanceProfile`。`task advance --profile auto` 先将 candidate profile 经 `harness.json.workflowPolicy.dag.profileRouting` 映射,再在 candidate delivery signal 含 `loop-agent-runtime-paths`、`scripts-ci-harness-paths` 或 `public-contract-paths` 时应用 M4 `supervised-quality-gate` promotion;`profileRouting.routingReasons` 记录确定性 reason。无 profile `task advance <task-id>` 仍为 standard-compatible;显式 `--profile minimal|standard|reviewed|supervised` 与自动 promotion 记录治理强度,已识别的前端业务 workflow 仍使用前端专用模板。高风险 task 应用 `--profile auto` 或显式 `--profile supervised`,而非显式 `--profile reviewed`。
|
|
70
70
|
- **Executor model routing**:DAG spec 选 `executor` 与 `complexity`,可通过 `executorModels.pi` 覆盖模型。值写成 `provider/model` 时显式选择 Pi provider(只分割第一个 `/`);裸模型名继续走内置映射或默认 `wizard-local`。默认 routing:Pi LOW=`gpt-5.3-codex-spark`、MED=`gpt-5.5`、HIGH=`gpt-5.5`。`shell` 不用 model,忽略 `executorModels`。
|
|
71
71
|
- **Active visibility**:真实 `dag execute` execution 在 run/node 转换时写 active `state.json`,归档前 core runner 暴露 isolated `DagRunObserver` hook 供 derived view。`.harness/dag-runs/completed/<run-id>/` / `paused/<run-id>/` 仍是 source of truth;observer 输出非 canonical。
|