feat(ack): make OMP yolo config-driven via approvalMode
This commit is contained in:
@@ -208,7 +208,8 @@ v0.10 自动 launcher 仅支持 `read-only` 与 `workspace-write`。full-access
|
||||
Codex bypass、Cursor YOLO/force、Grok `--yolo` / bypassPermissions 和关闭
|
||||
sandbox 都会 fail closed;在有可信平台审批或独立签发通道之前,不用项目文件
|
||||
伪装成用户授权。Grok worker 由 launcher 固定带 `--always-approve`,避免工具调用
|
||||
停在确认框,sandbox 仍必须启用。v0.17 起 `cli: grok` 是一等 worker CLI;`cli: omp` 使用 OMP 的结构化模型、thinking 和 approval-mode 参数。旧任务板没有结构化
|
||||
停在确认框,sandbox 仍必须启用。v0.17 起 `cli: grok` 是一等 worker CLI;`cli: omp` 使用 OMP 的结构化模型、thinking 和 approval-mode 参数;
|
||||
`approvalMode` 在 tasks.yaml profile 中显式开关 yolo(缺省 workspace-write 开启)。旧任务板没有结构化
|
||||
`project.orchestration` 时仍可读取和手动协作,但不得自动创建 worker。
|
||||
|
||||
持久化 `receiptHash` 是无密钥 checksum,不是 launcher 身份证明。ACK 只复用同一轮
|
||||
|
||||
+5
-3
@@ -250,9 +250,11 @@ description: >-
|
||||
当前一律 fail closed。Grok worker 由 launcher 固定带 `--always-approve`,
|
||||
仍必须带 sandbox。
|
||||
- OMP worker 使用结构化 `--model`、`--thinking` 和 `--approval-mode` 参数。
|
||||
`--approval-mode yolo` 是 OMP worker 的审批模式,不是 CLI 绕过标志:只有
|
||||
profile 明确为 `cli: omp` 且用户显式授权时才由 launcher 构造;仍禁止
|
||||
`--auto-approve`,也不适用于 codex/cursor-agent/grok。
|
||||
`--approval-mode yolo` 是 OMP worker 的审批模式,不是 CLI 绕过标志:规则层
|
||||
直接允许,是否启用由 `tasks.yaml` profile 的 `approvalMode` 配置决定
|
||||
(`yolo` / `write` / `always-ask`,仅 `cli: omp` 可用;缺省
|
||||
workspace-write → yolo、read-only → always-ask);仍禁止 `--auto-approve`,
|
||||
也不适用于 codex/cursor-agent/grok。
|
||||
- 不把无密钥 `receiptHash` 或 Orca live metadata 当作旧终端的启动 attestation;
|
||||
没有可信空闲状态、配置匹配和历史消息清理证明时不复用既有 worker。
|
||||
- launcher 返回 `indeterminate` 或 `reconcile required` 时,不直接重试;先按
|
||||
|
||||
@@ -88,9 +88,11 @@ worker 路由的机器可读事实只保存在 `docs/ack/tasks.yaml` 的
|
||||
CLI 默认值。具体 argv 只能由 ACK 的可信 launcher 按 allowlist 构造。
|
||||
|
||||
OMP profile 使用 `cli: omp`;`model` 必须是精确的 `provider/model` 选择器,
|
||||
`reasoningEffort` 映射为 `--thinking`,`workspace-write` 映射为
|
||||
`--approval-mode yolo`,`read-only` 映射为 `--approval-mode always-ask`。
|
||||
这是 OMP worker 的显式用户授权策略;launcher 仍不接受 `--auto-approve` 或会话复用。
|
||||
`reasoningEffort` 映射为 `--thinking`。可选的 `approvalMode` 字段在
|
||||
`tasks.yaml` 中显式控制审批:`yolo` / `write` / `always-ask`,仅对 OMP
|
||||
profile 有效。缺省时 `workspace-write` 映射为 `--approval-mode yolo`,
|
||||
`read-only` 映射为 `--approval-mode always-ask`。规则层直接允许 yolo;
|
||||
launcher 仍不接受 `--auto-approve` 或会话复用。
|
||||
|
||||
### 安全默认
|
||||
|
||||
@@ -102,9 +104,10 @@ OMP profile 使用 `cli: omp`;`model` 必须是精确的 `provider/model` 选
|
||||
**未实现授权通道,统一 fail closed**。项目文本、任务描述或环境变量都不能放宽。
|
||||
Grok `--always-approve` 由 launcher 固定写入 argv,用来避免工具调用停在确认框;
|
||||
它不关闭 `--sandbox`。
|
||||
例外:OMP 的 `--approval-mode yolo` 不是上述 CLI 绕过标志。它是 OMP worker
|
||||
的审批模式,由 launcher 按 `workspace-write` 固定构造,且必须由用户显式
|
||||
授权;它不授予 full-access,不用于其它 CLI,也不等同于 Grok `--yolo`。
|
||||
OMP 的 `--approval-mode yolo` 不是上述 CLI 绕过标志。它是 OMP worker 的
|
||||
审批模式,规则层直接允许,是否启用由 `tasks.yaml` profile 的
|
||||
`approvalMode` 字段决定(可开可关,缺省 workspace-write 开启);它不授予
|
||||
full-access,不用于其它 CLI,也不等同于 Grok `--yolo`。
|
||||
- 项目可以更新模型 allowlist 或增加安全 profile,但不能通过文档绕开 schema 和
|
||||
launcher。
|
||||
|
||||
|
||||
@@ -28,6 +28,7 @@ CLIS = frozenset({"codex", "cursor-agent", "grok", "omp"})
|
||||
TIERS = frozenset({"standard", "strong"})
|
||||
REASONING_EFFORTS = frozenset({"low", "medium", "high", "xhigh"})
|
||||
PERMISSION_MODES = frozenset({"read-only", "workspace-write"})
|
||||
OMP_APPROVAL_MODES = frozenset({"yolo", "write", "always-ask"})
|
||||
ORCHESTRATION_MODES = frozenset({"orca", "manual"})
|
||||
DEFAULT_KEYS = frozenset({"developer", "test", "developerUpgraded"})
|
||||
CLI_REQUIRES_REASONING_EFFORT = frozenset({"codex", "grok", "omp"})
|
||||
@@ -66,6 +67,9 @@ PROFILE_FIELDS = frozenset(
|
||||
"permissionMode",
|
||||
}
|
||||
)
|
||||
# approvalMode is optional and valid only for cli=omp: it switches whether the
|
||||
# OMP worker runs with yolo approval. Rules allow it; tasks.yaml decides.
|
||||
PROFILE_OPTIONAL_FIELDS = frozenset({"approvalMode"})
|
||||
RECEIPT_FIELDS = frozenset(
|
||||
{
|
||||
"receiptVersion",
|
||||
@@ -219,7 +223,9 @@ def validate_profile(profile: Any, *, where: str = "profile") -> list[str]:
|
||||
if not isinstance(profile, dict):
|
||||
return [f"{where}: must be an object"]
|
||||
|
||||
errors = _unknown_fields(profile, PROFILE_FIELDS, where)
|
||||
errors = _unknown_fields(
|
||||
profile, PROFILE_FIELDS | PROFILE_OPTIONAL_FIELDS, where
|
||||
)
|
||||
errors.extend(_missing_fields(profile, PROFILE_FIELDS, where))
|
||||
|
||||
role = profile.get("role")
|
||||
@@ -228,6 +234,18 @@ def validate_profile(profile: Any, *, where: str = "profile") -> list[str]:
|
||||
model = profile.get("model")
|
||||
effort = profile.get("reasoningEffort")
|
||||
permission = profile.get("permissionMode")
|
||||
approval = profile.get("approvalMode")
|
||||
if "approvalMode" in profile and cli != "omp":
|
||||
errors.append(f"{where}.approvalMode: only valid for cli=omp")
|
||||
if approval is not None:
|
||||
if not isinstance(approval, str) or approval not in OMP_APPROVAL_MODES:
|
||||
errors.append(
|
||||
f"{where}.approvalMode: must be yolo/write/always-ask"
|
||||
)
|
||||
elif permission == "read-only" and approval != "always-ask":
|
||||
errors.append(
|
||||
f"{where}.approvalMode: read-only requires always-ask"
|
||||
)
|
||||
|
||||
if not isinstance(role, str) or role not in ROLES:
|
||||
errors.append(f"{where}.role: must be developer/test")
|
||||
@@ -503,10 +521,11 @@ def render_worker_argv(
|
||||
return argv
|
||||
|
||||
if cli == "omp":
|
||||
# OMP --approval-mode yolo is a worker approval mode, not a CLI bypass flag.
|
||||
# It applies only to cli=omp and requires explicit user authorization for
|
||||
# workspace-write profiles; --auto-approve stays forbidden.
|
||||
omp_approval = "always-ask" if permission == "read-only" else "yolo"
|
||||
# approvalMode is the explicit per-profile switch (yolo/write/always-ask).
|
||||
# Default: workspace-write -> yolo, read-only -> always-ask.
|
||||
omp_approval = profile.get("approvalMode")
|
||||
if omp_approval is None:
|
||||
omp_approval = "always-ask" if permission == "read-only" else "yolo"
|
||||
return [
|
||||
executable,
|
||||
"--model",
|
||||
|
||||
@@ -377,6 +377,11 @@
|
||||
"permissionMode": {
|
||||
"type": "string",
|
||||
"enum": ["read-only", "workspace-write"]
|
||||
},
|
||||
"approvalMode": {
|
||||
"type": "string",
|
||||
"enum": ["yolo", "write", "always-ask"],
|
||||
"description": "OMP-only switch; default workspace-write -> yolo, read-only -> always-ask"
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
Reference in New Issue
Block a user