feat(ack): make OMP yolo config-driven via approvalMode
This commit is contained in:
@@ -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",
|
||||
|
||||
Reference in New Issue
Block a user