feat: add deployer
This commit is contained in:
@@ -46,6 +46,9 @@ def executable_basename_matches_cli(executable: str, cli: str) -> bool:
|
||||
return True
|
||||
return cli == "grok" and GROK_EXECUTABLE_NAME_RE.fullmatch(name) is not None
|
||||
|
||||
# allowedWorktrees 已废弃(v0.19 起):新任务板不再配置,旧任务板遗留该字段仍被容忍。
|
||||
# ORCHESTRATION_FIELDS 是“允许出现”的字段全集(含废弃字段),
|
||||
# REQUIRED_ORCHESTRATION_FIELDS 是“必须存在”的子集(不含废弃字段)。
|
||||
ORCHESTRATION_FIELDS = frozenset(
|
||||
{
|
||||
"profileVersion",
|
||||
@@ -56,6 +59,15 @@ ORCHESTRATION_FIELDS = frozenset(
|
||||
"defaults",
|
||||
}
|
||||
)
|
||||
REQUIRED_ORCHESTRATION_FIELDS = frozenset(
|
||||
{
|
||||
"profileVersion",
|
||||
"mode",
|
||||
"modelAllowlist",
|
||||
"profiles",
|
||||
"defaults",
|
||||
}
|
||||
)
|
||||
PROFILE_FIELDS = frozenset(
|
||||
{
|
||||
"role",
|
||||
@@ -341,11 +353,10 @@ def validate_orchestration(
|
||||
return [f"{where}: must be an object"]
|
||||
|
||||
errors = _unknown_fields(orchestration, ORCHESTRATION_FIELDS, where)
|
||||
errors.extend(_missing_fields(orchestration, ORCHESTRATION_FIELDS, where))
|
||||
errors.extend(_missing_fields(orchestration, REQUIRED_ORCHESTRATION_FIELDS, where))
|
||||
|
||||
profile_version = orchestration.get("profileVersion")
|
||||
mode = orchestration.get("mode")
|
||||
allowed_worktrees = orchestration.get("allowedWorktrees")
|
||||
allowlist = orchestration.get("modelAllowlist")
|
||||
profiles = orchestration.get("profiles")
|
||||
defaults = orchestration.get("defaults")
|
||||
@@ -355,20 +366,9 @@ def validate_orchestration(
|
||||
if not isinstance(mode, str) or mode not in ORCHESTRATION_MODES:
|
||||
errors.append(f"{where}.mode: must be orca/manual")
|
||||
|
||||
if not isinstance(allowed_worktrees, list):
|
||||
errors.append(f"{where}.allowedWorktrees: must be a list")
|
||||
else:
|
||||
if mode == "orca" and not allowed_worktrees:
|
||||
errors.append(f"{where}.allowedWorktrees: Orca mode requires at least one path")
|
||||
seen_worktrees: set[str] = set()
|
||||
for index, worktree in enumerate(allowed_worktrees):
|
||||
item_where = f"{where}.allowedWorktrees[{index}]"
|
||||
if not _is_absolute_safe_path(worktree):
|
||||
errors.append(f"{item_where}: must be a safe absolute path other than root")
|
||||
elif worktree in seen_worktrees:
|
||||
errors.append(f"{item_where}: duplicate worktree {worktree!r}")
|
||||
else:
|
||||
seen_worktrees.add(worktree)
|
||||
# allowedWorktrees 已废弃:worker 默认在 --project-root 工作,
|
||||
# 其它 worktree 由 launcher 按“同 git 仓库且已注册”约束(capture_worktree_identity)。
|
||||
# 旧任务板中遗留的该字段被容忍,不再校验。
|
||||
|
||||
errors.extend(_validate_model_allowlist(allowlist, f"{where}.modelAllowlist"))
|
||||
|
||||
@@ -757,11 +757,6 @@ def validate_worker_receipt(
|
||||
profile = candidate
|
||||
else:
|
||||
errors.append(f"{where}.profileId: unknown profile {profile_id!r}")
|
||||
allowed = orchestration.get("allowedWorktrees")
|
||||
if isinstance(worktree, dict) and isinstance(allowed, list):
|
||||
if worktree.get("path") not in allowed:
|
||||
errors.append(f"{where}.worktree.path: is not in allowedWorktrees")
|
||||
|
||||
if profile is not None:
|
||||
try:
|
||||
expected_profile_hash = profile_hash(
|
||||
|
||||
Reference in New Issue
Block a user