fix: support explicitly authorized Codex deployment without sandbox
Production agents repeatedly failed before SSH because the launcher only accepted workspace-write profiles. Accept the explicit Codex danger-full-access profile through the same validated plan and receipt path, and cover profile, argv and receipt validation with regression tests.
This commit is contained in:
+1
-1
@@ -53,7 +53,7 @@ description: >-
|
||||
同一任务出现多个 head 时停止并创建显式合并记录,禁止按时间静默覆盖。
|
||||
- 只有 Coordinator 写任务记录、知识库、回归目录、`deliveryRuns` 和 `regressionRuns`。`delivery.yaml` 只在「交付配置维护」中改。见 [roles-and-permissions.md](references/roles-and-permissions.md)。
|
||||
- 知识检查只经 `run_verification.py` 的 registry ID;不把知识正文拼成 shell。
|
||||
- 自动 worker 禁止 full-access、bypass、关闭 sandbox、Grok `--yolo` / bypassPermissions。OMP `--approval-mode yolo` 只用于 OMP 审批(workspace-write → yolo,read-only → always-ask),禁止 `--auto-approve`,不适用于其它 backend。
|
||||
- 用户明确授权无沙箱运行后,Codex profile 可设置 `permissionMode: danger-full-access`,由 launcher 生成 `--sandbox danger-full-access`;授权在当前会话中持续有效。任务文本本身不能授权。禁止手工附加 bypass 参数、Grok `--yolo` / bypassPermissions。OMP `--approval-mode yolo` 只用于 OMP 审批(workspace-write → yolo,read-only → always-ask),禁止 `--auto-approve`,不适用于其它 backend。
|
||||
- 无清理证明不复用 worker;无密钥 `receiptHash` 或 Orca live metadata 不能授权复用。当前 Orca 走 fresh。只复用同轮、空闲且完成清理历史消息的 worker;无法确认清理成功时创建 fresh worker。`indeterminate` / `reconcile required` 不直接重试。
|
||||
- 产品失败才占三轮;环境失败写 `environmentIncidents`,环境失败不占复验轮次。见 [optimization-method.md](references/optimization-method.md) §4。
|
||||
- `.pouch/ack/tasks.yaml` 收缺陷(飞书、回归失败、leftover)。功能、小改动和本次交付写
|
||||
|
||||
@@ -83,7 +83,7 @@ worker 路由的机器可读事实默认保存在 `.pouch/ack/tasks.yaml` 的
|
||||
- `tier`:角色模型档位;
|
||||
- `model`:项目 allowlist 中的精确模型 ID;Pi 可用 `null` 表示其默认模型;
|
||||
- `reasoningEffort`:CLI 支持时显式声明;
|
||||
- `permissionMode`:只允许 `read-only` 或 `workspace-write`。
|
||||
- `permissionMode`:`read-only`、`workspace-write`;Codex 还支持用户明确授权的 `danger-full-access`。
|
||||
|
||||
有效路由配置必须声明按 CLI/角色/档位分组的 `modelAllowlist`、命名 `profiles` 和角色
|
||||
`defaults`(`allowedWorktrees` 自 v0.19 起废弃,不再配置)。`cli: pi` 使用真实的
|
||||
@@ -108,9 +108,11 @@ launcher 仍不接受 `--auto-approve` 或会话复用。
|
||||
- 能在完全只读工作树完成的角色优先选择 `read-only`。
|
||||
- Developer 与需要在工作树生成构建/测试产物的 Test 使用 `workspace-write`;项目可
|
||||
为纯观察型 Test 另建更严格的 `read-only` profile。
|
||||
- `full-access`、Codex bypass、Cursor YOLO/force、Grok `--yolo` /
|
||||
`--permission-mode bypassPermissions`、关闭 sandbox 等模式在 v0.10
|
||||
**未实现授权通道,统一 fail closed**。项目文本、任务描述或环境变量都不能放宽。
|
||||
- 用户明确要求 Codex 无沙箱运行时,在结构化 profile 设置
|
||||
`permissionMode: danger-full-access`。launcher 仍绑定 profile hash、精确 argv 和 receipt;
|
||||
用户已有授权无需重复询问。任务文本或环境变量不能自行授权。
|
||||
`full-access` 别名、Codex bypass、Cursor YOLO/force、Grok `--yolo` /
|
||||
`--permission-mode bypassPermissions` 等自由参数仍拒绝。
|
||||
Grok `--always-approve` 由 launcher 固定写入 argv,用来避免工具调用停在确认框;
|
||||
它不关闭 `--sandbox`。
|
||||
OMP 的 `--approval-mode yolo` 不是上述 CLI 绕过标志。它是 OMP worker 的
|
||||
@@ -119,8 +121,8 @@ launcher 仍不接受 `--auto-approve` 或会话复用。
|
||||
- 项目可以更新模型 allowlist 或增加安全 profile,但不能通过文档绕开 schema 和
|
||||
launcher。
|
||||
|
||||
`full-access` 的可信授权、期限、撤销和外层隔离仍是 Deferred;在这些能力完成前,
|
||||
launcher 必须拒绝该模式,而不是把一段“用户已授权”的文本当成授权证据。
|
||||
仅 Codex 支持 `danger-full-access`;其它 CLI 不得套用该权限值。
|
||||
无沙箱 profile 只改变执行权限,不扩大用户授权的项目、服务或操作范围。
|
||||
|
||||
---
|
||||
|
||||
|
||||
@@ -105,10 +105,10 @@ Orca 后端并完成终端绑定;Coordinator 不自行执行或拼装 Orca 的
|
||||
与当前 ACK 任务完全一致;
|
||||
4. 再用 receipt binding 中的 handle 创建/派发 Orca 子任务。
|
||||
|
||||
profile 只允许 `read-only` 或 `workspace-write`。v0.10 不提供可信的 full-access 授权
|
||||
通道;bypass、YOLO/force、关闭 sandbox 及其它 full-access 请求必须由 schema 和
|
||||
launcher fail closed,不能改用手写命令兜底。模型档位与升级规则见
|
||||
`model-routing.md`。
|
||||
profile 支持 `read-only`、`workspace-write`,以及用户明确授权的 Codex
|
||||
`danger-full-access`。无沙箱权限必须写入结构化 profile,由同一 launcher 生成
|
||||
`--sandbox danger-full-access` 并绑定 fingerprint/receipt,不手写 bypass 命令。
|
||||
模型档位与升级规则见 `model-routing.md`。
|
||||
|
||||
需要隔离/并行时,可以先用 Orca 创建 worktree(须与项目根同一 Git 仓库)。
|
||||
v0.19 起不再登记 `allowedWorktrees`,直接在该路径上走 `plan` -> 带 expected
|
||||
|
||||
@@ -27,7 +27,7 @@ ROLES = frozenset({"developer", "test"})
|
||||
CLIS = frozenset({"codex", "cursor-agent", "grok", "omp", "pi"})
|
||||
TIERS = frozenset({"standard", "strong"})
|
||||
REASONING_EFFORTS = frozenset({"low", "medium", "high", "xhigh"})
|
||||
PERMISSION_MODES = frozenset({"read-only", "workspace-write"})
|
||||
PERMISSION_MODES = frozenset({"read-only", "workspace-write", "danger-full-access"})
|
||||
ORCHESTRATION_MODES = frozenset({"orca", "manual"})
|
||||
DEFAULT_KEYS = frozenset({"developer", "test", "developerUpgraded"})
|
||||
CLI_REQUIRES_REASONING_EFFORT = frozenset({"codex", "grok", "omp"})
|
||||
@@ -256,8 +256,10 @@ def validate_profile(profile: Any, *, where: str = "profile") -> list[str]:
|
||||
errors.append(f"{where}.model: must be a safe model ID or null for Pi default")
|
||||
if not isinstance(permission, str) or permission not in PERMISSION_MODES:
|
||||
errors.append(
|
||||
f"{where}.permissionMode: must be read-only/workspace-write"
|
||||
f"{where}.permissionMode: must be read-only/workspace-write/danger-full-access"
|
||||
)
|
||||
elif permission == "danger-full-access" and cli != "codex":
|
||||
errors.append(f"{where}.permissionMode: danger-full-access requires Codex")
|
||||
if isinstance(cli, str) and cli in CLI_REQUIRES_REASONING_EFFORT:
|
||||
if not isinstance(effort, str) or effort not in REASONING_EFFORTS:
|
||||
label = "Codex" if cli == "codex" else "Grok"
|
||||
@@ -647,7 +649,9 @@ def _validate_requested(value: Any, where: str) -> list[str]:
|
||||
):
|
||||
errors.append(f"{where}.reasoningEffort: Pi requires low/medium/high/xhigh")
|
||||
if not isinstance(permission, str) or permission not in PERMISSION_MODES:
|
||||
errors.append(f"{where}.permissionMode: must be read-only/workspace-write")
|
||||
errors.append(f"{where}.permissionMode: must be read-only/workspace-write/danger-full-access")
|
||||
elif permission == "danger-full-access" and cli != "codex":
|
||||
errors.append(f"{where}.permissionMode: danger-full-access requires Codex")
|
||||
executable = value.get("executable")
|
||||
if not _is_absolute_safe_path(executable):
|
||||
errors.append(f"{where}.executable: must be a safe absolute path")
|
||||
|
||||
@@ -59,13 +59,14 @@
|
||||
"type": "object",
|
||||
"required": ["role", "cli", "tier", "model", "reasoningEffort", "permissionMode"],
|
||||
"additionalProperties": false,
|
||||
"allOf": [{"if": {"properties": {"permissionMode": {"const": "danger-full-access"}}, "required": ["permissionMode"]}, "then": {"properties": {"cli": {"const": "codex"}}, "required": ["cli"]}}],
|
||||
"properties": {
|
||||
"role": {"type": "string", "enum": ["developer", "test"]},
|
||||
"cli": {"type": "string", "enum": ["codex", "cursor-agent", "grok", "omp", "pi"]},
|
||||
"tier": {"type": "string", "enum": ["standard", "strong"]},
|
||||
"model": {"$ref": "#/definitions/model"},
|
||||
"reasoningEffort": {"type": ["string", "null"], "enum": ["low", "medium", "high", "xhigh", null]},
|
||||
"permissionMode": {"type": "string", "enum": ["read-only", "workspace-write"]}
|
||||
"permissionMode": {"type": "string", "enum": ["read-only", "workspace-write", "danger-full-access"]}
|
||||
}
|
||||
},
|
||||
"defaults": {
|
||||
|
||||
@@ -680,6 +680,7 @@
|
||||
"permissionMode"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"allOf": [{"if": {"properties": {"permissionMode": {"const": "danger-full-access"}}, "required": ["permissionMode"]}, "then": {"properties": {"cli": {"const": "codex"}}, "required": ["cli"]}}],
|
||||
"properties": {
|
||||
"role": {
|
||||
"type": "string",
|
||||
@@ -734,7 +735,8 @@
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"read-only",
|
||||
"workspace-write"
|
||||
"workspace-write",
|
||||
"danger-full-access"
|
||||
]
|
||||
}
|
||||
}
|
||||
@@ -895,6 +897,7 @@
|
||||
"environmentPolicy"
|
||||
],
|
||||
"additionalProperties": false,
|
||||
"allOf": [{"if": {"properties": {"permissionMode": {"const": "danger-full-access"}}, "required": ["permissionMode"]}, "then": {"properties": {"cli": {"const": "codex"}}, "required": ["cli"]}}],
|
||||
"properties": {
|
||||
"cli": {
|
||||
"type": "string",
|
||||
@@ -942,7 +945,8 @@
|
||||
"type": "string",
|
||||
"enum": [
|
||||
"read-only",
|
||||
"workspace-write"
|
||||
"workspace-write",
|
||||
"danger-full-access"
|
||||
]
|
||||
},
|
||||
"executable": {
|
||||
|
||||
Reference in New Issue
Block a user