Skip to content

Commit 6df6a8b

Browse files
authored
fix(control-plane): require explicit mutation actors (#4816)
1 parent 632d037 commit 6df6a8b

38 files changed

Lines changed: 314 additions & 32 deletions

‎apps/presentation/dashboard/README.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,8 +207,8 @@ It provides a unified, coherent experience for managing long-running agent Goals
207207

208208
```bash
209209
loopx goal-lifecycle --goal-id <goal-id> --operation stop
210-
loopx goal-lifecycle --goal-id <goal-id> --operation stop --execute
211-
loopx goal-lifecycle --goal-id <goal-id> --operation resume --execute
210+
loopx goal-lifecycle --goal-id <goal-id> --operation stop --actor-kind owner --execute
211+
loopx goal-lifecycle --goal-id <goal-id> --operation resume --actor-kind owner --execute
212212
loopx quota status --goal-id <goal-id>
213213
```
214214

‎docs/book/chapters/workspace-v1.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,10 +101,13 @@ Preview 冻结规范化参数、影响范围和当前 revision。Apply 只能执
101101

102102
```bash
103103
loopx goal-lifecycle --goal-id <goal-id> --operation stop
104-
loopx goal-lifecycle --goal-id <goal-id> --operation stop --execute
104+
loopx goal-lifecycle --goal-id <goal-id> --operation stop --actor-kind owner --execute
105105
loopx quota status --goal-id <goal-id>
106106
```
107107

108+
执行 lifecycle transition 时必须显式传入 `--actor-kind owner` 或 `controller`;
109+
匿名预览仍然保持只读。
110+
108111
暂停会让该 Goal 退出 active attention,并使有效自动运行 quota 投影为 0;Todo、历史、证据和配置
109112
仍保留。恢复使用显式 `resume --execute`,且不会绕过 Todo、Gate 或 quota。不要把 stop 写成
110113
“完成 Goal”,也不要用改 quota 的方式意外恢复一个被 owner 停止的 Goal。

‎docs/book/en/chapters/workspace-v1.md‎

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,13 @@ For example, the first Goal-stop command is preview-only:
111111

112112
```bash
113113
loopx goal-lifecycle --goal-id <goal-id> --operation stop
114-
loopx goal-lifecycle --goal-id <goal-id> --operation stop --execute
114+
loopx goal-lifecycle --goal-id <goal-id> --operation stop --actor-kind owner --execute
115115
loopx quota status --goal-id <goal-id>
116116
```
117117

118+
Executed lifecycle transitions require an explicit `--actor-kind owner` or
119+
`controller`; anonymous previews remain read-only.
120+
118121
Stopping a Goal removes it from active attention and projects zero effective automatic-run quota while
119122
preserving Todos, history, evidence, and configuration. Explicit `resume --execute` restores scheduling
120123
eligibility but does not bypass Todo, Gate, or quota rules. Do not describe stop as completing the Goal, and

‎docs/guides/codex-app-autonomous-goal-experience.md‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -207,7 +207,7 @@ loopx history --goal-id "$GOAL_ID"
207207

208208
```bash
209209
loopx goal-lifecycle --goal-id "$GOAL_ID" --operation stop
210-
loopx goal-lifecycle --goal-id "$GOAL_ID" --operation stop --execute
210+
loopx goal-lifecycle --goal-id "$GOAL_ID" --operation stop --actor-kind owner --execute
211211
```
212212

213213
**预期效果:**
@@ -225,7 +225,7 @@ loopx goal-lifecycle --goal-id "$GOAL_ID" --operation stop --execute
225225
**输入:**
226226

227227
```bash
228-
loopx goal-lifecycle --goal-id "$GOAL_ID" --operation resume --execute
228+
loopx goal-lifecycle --goal-id "$GOAL_ID" --operation resume --actor-kind owner --execute
229229
loopx quota should-run \
230230
--goal-id "$GOAL_ID" \
231231
--agent-id "$AGENT_ID" \

‎docs/guides/getting-started.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -866,6 +866,7 @@ loopx operator-gate \
866866

867867
loopx reward \
868868
--goal-id your-project-goal \
869+
--actor-kind owner \
869870
--decision continue_route \
870871
--reward positive \
871872
--reason-summary "validation improved and the route is worth extending"

‎docs/guides/personal-workspace-user-guide.md‎

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,13 +108,16 @@ CLI 提供同一套可预览、可验证的生命周期操作:
108108
loopx goal-lifecycle --goal-id <goal-id> --operation stop
109109

110110
# 确认执行,再读取 quota 验证自动推进已暂停
111-
loopx goal-lifecycle --goal-id <goal-id> --operation stop --execute
111+
loopx goal-lifecycle --goal-id <goal-id> --operation stop --actor-kind owner --execute
112112
loopx quota status --goal-id <goal-id>
113113

114114
# 恢复;不会绕过其他运行门禁
115-
loopx goal-lifecycle --goal-id <goal-id> --operation resume --execute
115+
loopx goal-lifecycle --goal-id <goal-id> --operation resume --actor-kind owner --execute
116116
```
117117

118+
`--execute` 必须显式声明 `--actor-kind owner` 或 `controller`;不带 actor 的
119+
预览仍保持只读。写入的 activation receipt 会保留该 actor kind。
120+
118121
执行时,LoopX 会写入权威 source registry、同步全局 registry,并验证两端 readback;任一端未验证成功时不会宣称操作完成。
119122

120123
切换到 SSH 状态来源后,只有来源与本机 OpenSSH 配置中的精确 Host alias 绑定时,

‎docs/heartbeat-automation-prompt.md‎

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -658,7 +658,9 @@ hint directly, otherwise do nothing. For the uniquely matched current heartbeat,
658658

659659
If `automation_update` is unavailable in the session and
660660
`scheduler_hint.app_automation.fallback_hint.available=true`, run the bound
661-
`fallback_hint.cli_args` (`loopx-apply-rrule`) once instead. It backs up
661+
`fallback_hint.cli_args` (`loopx-apply-rrule`) once instead. The fallback
662+
requires the projected registered `--agent-id`; there is no implicit Agent
663+
default. It backs up
662664
`codex-dev.db`, syncs the automation TOML and SQLite row, and runs the bound
663665
ACK; direct SQLite edits bypass the app API, so this is a bounded fallback and
664666
never the routine path. The bridge reuses the provided parent Turn for its

‎docs/integration.md‎

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -573,12 +573,17 @@ editing the run JSON by hand:
573573
```bash
574574
loopx reward \
575575
--goal-id project-goal \
576+
--actor-kind owner \
576577
--decision continue_route \
577578
--reward positive \
578579
--reason-summary "comparable validation improved and the route is worth extending" \
579580
--follow-up "promote to the next longer-window check"
580581
```
581582

583+
Durable reward writes require an explicit `--actor-kind owner` or
584+
`--actor-kind controller`; `--dry-run` remains available without an actor.
585+
The selected kind is stored with the run-bound overlay.
586+
582587
By default the command attaches feedback to the latest compact run for the
583588
goal. Pass `--run-generated-at <timestamp>` to target an older run. The writer
584589
appends a JSONL overlay to the same `index.jsonl`; it does not mutate private
@@ -604,6 +609,7 @@ overlay instead of creating a separate memory store:
604609
```bash
605610
loopx reward \
606611
--goal-id project-goal \
612+
--actor-kind owner \
607613
--decision route_correction \
608614
--reward mixed \
609615
--reason-summary "fix lifecycle counters before adding more benchmark cases" \
@@ -629,6 +635,7 @@ the durable loop in one CLI call:
629635
```bash
630636
loopx reward \
631637
--goal-id project-goal \
638+
--actor-kind owner \
632639
--decision continue_route \
633640
--reward positive \
634641
--reason-summary "comparable validation improved and the route is worth extending" \

‎docs/product/roadmaps/experiment-controller-milestone.md‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ Use `loopx reward` to append this compact signal to an existing run:
102102
```bash
103103
loopx reward \
104104
--goal-id example-experiment-goal \
105+
--actor-kind owner \
105106
--run-generated-at 2026-06-01T00:00:00+00:00 \
106107
--decision continue_route \
107108
--reward positive \

‎docs/reference/contracts/dashboard-reward-write-boundary.md‎

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,9 @@ A browser append endpoint may be implemented only when all of these are true:
3838
- The payload has already passed the same validation as `/reward/dry-run`.
3939
- The response remains compact and does not return `index_path`, `json_path`,
4040
`markdown_path`, local absolute paths, or raw private evidence.
41+
- The trusted loopback adapter records `actor_kind=owner` in both preview and
42+
append receipts; the canonical CLI requires an explicit owner/controller
43+
actor kind for a durable write.
4144

4245
## Preview Handshake
4346

0 commit comments

Comments
 (0)