feat: add deployer

This commit is contained in:
2026-08-24 09:44:59 +08:00
parent 31bc5f45ce
commit e4d4319919
20 changed files with 1971 additions and 288 deletions
+16 -21
View File
@@ -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(