agent-exec transport 879b9a517efd4e3f85339649d5b00586/395b33d1abda

This commit is contained in:
agent-exec-transport
2026-10-16 19:02:36 +00:00
parent 179f03771a
commit 1c4acb40a4
3 changed files with 205 additions and 3 deletions
+12 -1
View File
@@ -19,7 +19,9 @@ candidate ends `unavailable` or `blocked`, and that result does not authorize
the host to write the unit. The legacy value `all-unavailable` remains the host to write the unit. The legacy value `all-unavailable` remains
parseable and likewise grants no host write authority. Cursor uses parseable and likewise grants no host write authority. Cursor uses
`cursor-agent-stable`. `model: auto` lets each CLI use its configured default `cursor-agent-stable`. `model: auto` lets each CLI use its configured default
model; PI therefore uses the operator-selected MiniMax default. model; PI therefore uses the operator-selected MiniMax default. The
`integration` block declares the host-exempt paths and the transport, admission,
and cleanup entry points.
```agent-execution ```agent-execution
schema: agent-execution/v1 schema: agent-execution/v1
@@ -66,4 +68,13 @@ profiles:
executable: codex executable: codex
model: auto model: auto
enabled: true enabled: true
integration:
exempt_paths: [".task/**", "docs/superpowers/specs/**", "docs/superpowers/plans/**"]
transport:
command: python3 scripts/agent_exec.py apply
admission:
command: python3 scripts/agent_exec.py admit
cleanup:
command: make task-finish
``` ```
+82 -2
View File
@@ -5,7 +5,7 @@ import ast
import re import re
from collections.abc import Mapping from collections.abc import Mapping
from dataclasses import dataclass from dataclasses import dataclass
from pathlib import Path from pathlib import Path, PurePosixPath
from typing import Any from typing import Any
SCHEMA_V1 = "agent-execution/v1" SCHEMA_V1 = "agent-execution/v1"
@@ -47,7 +47,17 @@ SECRET_VALUE_RE = re.compile(
r"(?i)^(bearer\s+\S+|sk-[A-Za-z0-9_\-]{8,}|[A-Fa-f0-9]{32,})$" r"(?i)^(bearer\s+\S+|sk-[A-Za-z0-9_\-]{8,}|[A-Fa-f0-9]{32,})$"
) )
ROOT_KEYS = frozenset({"schema", "execution", "roles", "profiles", "custom_adapters"}) ROOT_KEYS = frozenset(
{"schema", "execution", "roles", "profiles", "custom_adapters", "integration"}
)
INTEGRATION_KEYS = frozenset({"exempt_paths", "transport", "admission", "cleanup"})
ENTRYPOINT_KEYS = frozenset({"command"})
# Mirrors the host-managed prefixes enforced by scripts/agent_exec.py
# (_HOST_MANAGED_PREFIXES, the enforcement source). A declared
# integration.exempt_paths must equal this set so it cannot widen host authority.
HOST_EXEMPT_PATHS = frozenset(
{".task/**", "docs/superpowers/specs/**", "docs/superpowers/plans/**"}
)
EXECUTION_KEYS = frozenset( EXECUTION_KEYS = frozenset(
{ {
"fresh_process_per_unit", "fresh_process_per_unit",
@@ -116,6 +126,14 @@ class CustomAdapter:
output_format: str output_format: str
@dataclass(frozen=True)
class IntegrationConfig:
exempt_paths: tuple[str, ...]
transport_command: str
admission_command: str
cleanup_command: str
@dataclass(frozen=True) @dataclass(frozen=True)
class ExecutionConfig: class ExecutionConfig:
schema: str schema: str
@@ -123,6 +141,7 @@ class ExecutionConfig:
roles: Mapping[str, tuple[str, ...]] roles: Mapping[str, tuple[str, ...]]
profiles: Mapping[str, Profile] profiles: Mapping[str, Profile]
custom_adapters: Mapping[str, CustomAdapter] custom_adapters: Mapping[str, CustomAdapter]
integration: IntegrationConfig | None = None
def load_config(repo: Path) -> ExecutionConfig: def load_config(repo: Path) -> ExecutionConfig:
@@ -351,12 +370,17 @@ def _build_config(raw: dict[str, Any]) -> ExecutionConfig:
_validate_normal_role_adapters(profiles, roles) _validate_normal_role_adapters(profiles, roles)
_validate_normal_role_exactness(profiles, roles) _validate_normal_role_exactness(profiles, roles)
integration = None
if "integration" in raw:
integration = _build_integration(raw["integration"])
return ExecutionConfig( return ExecutionConfig(
schema=schema, schema=schema,
execution=execution, execution=execution,
roles=roles, roles=roles,
profiles=profiles, profiles=profiles,
custom_adapters=custom_adapters, custom_adapters=custom_adapters,
integration=integration,
) )
@@ -634,6 +658,62 @@ def _build_custom_adapters(raw: Any) -> dict[str, CustomAdapter]:
return out return out
def _build_integration(raw: Any) -> IntegrationConfig:
if not isinstance(raw, dict):
raise ConfigError("integration must be a mapping")
unknown = set(raw) - INTEGRATION_KEYS
if unknown:
raise ConfigError(f"unknown keys in integration: {sorted(unknown)}")
missing = INTEGRATION_KEYS - set(raw)
if missing:
raise ConfigError(f"missing keys in integration: {sorted(missing)}")
exempt_paths = _exempt_paths_tuple(raw["exempt_paths"])
if set(exempt_paths) != HOST_EXEMPT_PATHS:
raise ConfigError(
"integration.exempt_paths must exactly match the host-managed set "
f"{sorted(HOST_EXEMPT_PATHS)}; got {list(exempt_paths)}"
)
return IntegrationConfig(
exempt_paths=exempt_paths,
transport_command=_entrypoint_command(raw["transport"], "integration.transport"),
admission_command=_entrypoint_command(raw["admission"], "integration.admission"),
cleanup_command=_entrypoint_command(raw["cleanup"], "integration.cleanup"),
)
def _exempt_paths_tuple(value: Any) -> tuple[str, ...]:
if not isinstance(value, list) or not value:
raise ConfigError("integration.exempt_paths must be a non-empty list")
items: list[str] = []
for item in value:
if not isinstance(item, str) or not item:
raise ConfigError("integration.exempt_paths entries must be non-empty strings")
if item.startswith("/") or ".." in PurePosixPath(item).parts:
raise ConfigError(
f"integration.exempt_paths must be relative without '..': {item!r}"
)
if item in items:
raise ConfigError(f"duplicate integration.exempt_paths entry: {item!r}")
items.append(item)
return tuple(items)
def _entrypoint_command(raw: Any, label: str) -> str:
if not isinstance(raw, dict):
raise ConfigError(f"{label} must be a mapping")
unknown = set(raw) - ENTRYPOINT_KEYS
if unknown:
raise ConfigError(f"unknown keys in {label}: {sorted(unknown)}")
missing = ENTRYPOINT_KEYS - set(raw)
if missing:
raise ConfigError(f"missing keys in {label}: {sorted(missing)}")
command = raw["command"]
if not isinstance(command, str) or not command.strip():
raise ConfigError(f"{label}.command must be a non-empty string")
_reject_shell_or_secret_value(f"{label}.command", command)
return command
def _argv_tuple(value: Any, label: str) -> tuple[str, ...]: def _argv_tuple(value: Any, label: str) -> tuple[str, ...]:
if not isinstance(value, list): if not isinstance(value, list):
raise ConfigError(f"{label} must be a list") raise ConfigError(f"{label} must be a list")
+111
View File
@@ -792,6 +792,117 @@ class AgentExecConfigTests(unittest.TestCase):
self.assertTrue(cfg.profiles["codex"].enabled) self.assertTrue(cfg.profiles["codex"].enabled)
self.assertEqual(cfg.profiles["codex"].adapter, "codex") self.assertEqual(cfg.profiles["codex"].adapter, "codex")
def test_valid_integration_block_parses_and_is_exposed(self) -> None:
write_repo(self.repo, MINIMAL_BLOCK + "\n" + VALID_INTEGRATION)
cfg = load_config(self.repo)
self.assertIsNotNone(cfg.integration)
assert cfg.integration is not None
self.assertEqual(
cfg.integration.exempt_paths,
(".task/**", "docs/superpowers/specs/**", "docs/superpowers/plans/**"),
)
self.assertEqual(
cfg.integration.transport_command, "python3 scripts/agent_exec.py apply"
)
self.assertEqual(
cfg.integration.admission_command, "python3 scripts/agent_exec.py admit"
)
self.assertEqual(cfg.integration.cleanup_command, "make task-finish")
def test_missing_integration_still_parses_as_none(self) -> None:
write_repo(self.repo, MINIMAL_BLOCK)
self.assertIsNone(load_config(self.repo).integration)
def test_integration_rejects_unknown_and_missing_keys(self) -> None:
cases = {
"unknown key in integration": VALID_INTEGRATION.replace(
" cleanup:\n", " extra: x\n cleanup:\n"
),
"unknown key in transport": VALID_INTEGRATION.replace(
" command: python3 scripts/agent_exec.py apply\n",
" command: python3 scripts/agent_exec.py apply\n extra: x\n",
),
"missing cleanup": VALID_INTEGRATION.split(" cleanup:")[0],
}
for label, block in cases.items():
with self.subTest(label):
write_repo(self.repo, MINIMAL_BLOCK + "\n" + block)
with self.assertRaises(ConfigError):
load_config(self.repo)
def test_integration_exempt_paths_must_be_unique_nonempty_and_exact(self) -> None:
cases = {
"empty": 'exempt_paths: []',
"duplicate": (
'exempt_paths: [".task/**", ".task/**", '
'"docs/superpowers/specs/**", "docs/superpowers/plans/**"]'
),
"widened": (
'exempt_paths: [".task/**", "docs/superpowers/specs/**", '
'"docs/superpowers/plans/**", "src/**"]'
),
"narrowed": 'exempt_paths: [".task/**", "docs/superpowers/specs/**"]',
"parent traversal": (
'exempt_paths: [".task/**", "docs/superpowers/specs/**", '
'"docs/superpowers/plans/../../**"]'
),
"absolute": (
'exempt_paths: [".task/**", "docs/superpowers/specs/**", '
'"/docs/superpowers/plans/**"]'
),
}
for label, value in cases.items():
with self.subTest(label):
block = VALID_INTEGRATION.replace(
'exempt_paths: [".task/**", "docs/superpowers/specs/**", '
'"docs/superpowers/plans/**"]',
value,
)
write_repo(self.repo, MINIMAL_BLOCK + "\n" + block)
with self.assertRaises(ConfigError):
load_config(self.repo)
def test_integration_command_rejects_shell_metacharacters(self) -> None:
block = VALID_INTEGRATION.replace(
"command: python3 scripts/agent_exec.py apply",
"command: python3 scripts/agent_exec.py apply; rm -rf /",
)
write_repo(self.repo, MINIMAL_BLOCK + "\n" + block)
with self.assertRaises(ConfigError):
load_config(self.repo)
def test_host_exempt_paths_match_executor_enforcement(self) -> None:
from scripts import agent_exec
from scripts.agent_exec_config import HOST_EXEMPT_PATHS
enforced = {prefix.rstrip("/") for prefix in agent_exec._HOST_MANAGED_PREFIXES}
declared = {glob.removesuffix("/**") for glob in HOST_EXEMPT_PATHS}
self.assertEqual(declared, enforced)
def test_checked_in_project_config_declares_integration(self) -> None:
cfg = load_config(Path(__file__).resolve().parents[1])
self.assertIsNotNone(cfg.integration)
assert cfg.integration is not None
self.assertEqual(
set(cfg.integration.exempt_paths),
{".task/**", "docs/superpowers/specs/**", "docs/superpowers/plans/**"},
)
self.assertEqual(cfg.integration.cleanup_command, "make task-finish")
VALID_INTEGRATION = textwrap.dedent(
"""\
integration:
exempt_paths: [".task/**", "docs/superpowers/specs/**", "docs/superpowers/plans/**"]
transport:
command: python3 scripts/agent_exec.py apply
admission:
command: python3 scripts/agent_exec.py admit
cleanup:
command: make task-finish
"""
)
def _legacy_custom_block() -> str: def _legacy_custom_block() -> str:
"""No emergency_profile and adapter custom on every role.""" """No emergency_profile and adapter custom on every role."""