254 lines
10 KiB
Python
254 lines
10 KiB
Python
"""Canonical, declarative Capability Registry v1 for Emma."""
|
|
|
|
from dataclasses import dataclass
|
|
from enum import Enum
|
|
from types import MappingProxyType
|
|
from typing import Mapping, Tuple
|
|
|
|
|
|
class RiskLevel(str, Enum):
|
|
READ = "read"
|
|
WRITE = "write"
|
|
HIGH_IMPACT = "high_impact"
|
|
FORBIDDEN = "forbidden"
|
|
|
|
|
|
class Availability(str, Enum):
|
|
ACTIVE = "active"
|
|
PLANNED = "planned"
|
|
FORBIDDEN = "forbidden"
|
|
|
|
|
|
@dataclass(frozen=True)
|
|
class Capability:
|
|
id: str
|
|
display_name: str
|
|
description: str
|
|
category: str
|
|
risk_level: RiskLevel
|
|
availability: Availability
|
|
execution_owner: str
|
|
backend_tool: str | None
|
|
required_actor_scope: Tuple[str, ...]
|
|
input_schema: Mapping[str, str]
|
|
output_schema: Mapping[str, str]
|
|
approval_required: bool
|
|
approval_binding: str | None
|
|
audit_required: bool
|
|
rollback_required: bool
|
|
self_approval_forbidden: bool
|
|
allowed_targets: Tuple[str, ...]
|
|
external_source_policy: str | None
|
|
|
|
|
|
_EMPTY_SCHEMA: Mapping[str, str] = MappingProxyType({})
|
|
|
|
|
|
def _capability(
|
|
capability_id: str,
|
|
display_name: str,
|
|
description: str,
|
|
category: str,
|
|
risk_level: RiskLevel,
|
|
availability: Availability,
|
|
execution_owner: str,
|
|
backend_tool: str | None,
|
|
required_actor_scope: Tuple[str, ...],
|
|
approval_required: bool,
|
|
approval_binding: str | None,
|
|
audit_required: bool,
|
|
rollback_required: bool,
|
|
self_approval_forbidden: bool,
|
|
allowed_targets: Tuple[str, ...],
|
|
external_source_policy: str | None,
|
|
) -> Capability:
|
|
return Capability(
|
|
id=capability_id,
|
|
display_name=display_name,
|
|
description=description,
|
|
category=category,
|
|
risk_level=risk_level,
|
|
availability=availability,
|
|
execution_owner=execution_owner,
|
|
backend_tool=backend_tool,
|
|
required_actor_scope=required_actor_scope,
|
|
input_schema=_EMPTY_SCHEMA,
|
|
output_schema=_EMPTY_SCHEMA,
|
|
approval_required=approval_required,
|
|
approval_binding=approval_binding,
|
|
audit_required=audit_required,
|
|
rollback_required=rollback_required,
|
|
self_approval_forbidden=self_approval_forbidden,
|
|
allowed_targets=allowed_targets,
|
|
external_source_policy=external_source_policy,
|
|
)
|
|
|
|
|
|
_CAPABILITIES_TUPLE: Tuple[Capability, ...] = (
|
|
_capability(
|
|
"emma.chat", "Emma chat", "Conversational reasoning through Emma.",
|
|
"conversation", RiskLevel.READ, Availability.ACTIVE, "opax-mcp", "run_emma",
|
|
("authenticated_user",), False, None, True, False, False,
|
|
("opax.vauco.no",), "none",
|
|
),
|
|
_capability(
|
|
"emma.analyze_user_text", "Analyze user-provided text",
|
|
"Analyze, summarize, and structure text provided in the current request.",
|
|
"conversation", RiskLevel.READ, Availability.ACTIVE, "opax-mcp", "run_emma",
|
|
("authenticated_user",), False, None, True, False, False,
|
|
("user_provided_text",), "user_provided_only",
|
|
),
|
|
_capability(
|
|
"vauco.context.retrieve", "Retrieve approved VAUCO context",
|
|
"Retrieve approved VAUCO internal context.", "context", RiskLevel.READ,
|
|
Availability.PLANNED, "opax-mcp", None,
|
|
("authenticated_user", "vauco_context_read"), False, None, True, False, False,
|
|
("approved_vauco_sources",), "approved_internal_only",
|
|
),
|
|
_capability(
|
|
"conversation.session_history", "Retrieve active session history",
|
|
"Retrieve bounded history for the active user session.", "context", RiskLevel.READ,
|
|
Availability.PLANNED, "opax-web", None,
|
|
("authenticated_user", "conversation_read"), False, None, True, False, False,
|
|
("active_user_session",), "session_scoped",
|
|
),
|
|
_capability(
|
|
"memory.morphic.read", "Read scoped Morphic memory",
|
|
"Read actor-scoped Morphic memory.", "memory", RiskLevel.READ,
|
|
Availability.PLANNED, "opax-mcp", None,
|
|
("authenticated_user", "morphic_memory_read"), False, None, True, False, False,
|
|
("actor_scoped_memory",), "actor_scoped",
|
|
),
|
|
_capability(
|
|
"gitea.read_commits", "Read Gitea commits",
|
|
"Read commit history from the authoritative Gitea service.", "gitea", RiskLevel.READ,
|
|
Availability.PLANNED, "opax-mcp", "list_commits",
|
|
("authenticated_user", "gitea_read"), False, None, True, False, False,
|
|
("git.vauco.no",), "internal_authoritative_only",
|
|
),
|
|
_capability(
|
|
"gitea.read_file", "Read Gitea file",
|
|
"Read a file from the authoritative Gitea service.", "gitea", RiskLevel.READ,
|
|
Availability.PLANNED, "opax-mcp", "get_file",
|
|
("authenticated_user", "gitea_read"), False, None, True, False, False,
|
|
("git.vauco.no",), "internal_authoritative_only",
|
|
),
|
|
_capability(
|
|
"gitea.list_repo_files", "List Gitea repo files",
|
|
"List files in a directory from the authoritative Gitea service.", "gitea", RiskLevel.READ,
|
|
Availability.PLANNED, "opax-mcp", "list_repo_files",
|
|
("authenticated_user", "gitea_read"), False, None, True, False, False,
|
|
("git.vauco.no",), "internal_authoritative_only",
|
|
),
|
|
_capability(
|
|
"cloudbuild.read_status", "Read Cloud Build status",
|
|
"Read Cloud Build status in the approved VAUCO project.", "cloudbuild", RiskLevel.READ,
|
|
Availability.PLANNED, "opax-mcp", None,
|
|
("authenticated_user", "cloudbuild_read"), False, None, True, False, False,
|
|
("propane-will-491900-m5",), "internal_project_only",
|
|
),
|
|
_capability(
|
|
"cloudrun.read_status", "Read Cloud Run status",
|
|
"Read Cloud Run status in the approved VAUCO project.", "cloudrun", RiskLevel.READ,
|
|
Availability.PLANNED, "opax-mcp", None,
|
|
("authenticated_user", "cloudrun_read"), False, None, True, False, False,
|
|
("propane-will-491900-m5", "us-central1"), "internal_project_only",
|
|
),
|
|
_capability(
|
|
"github.intake.read", "Read reviewed external GitHub repository",
|
|
"Read an explicitly requested external repository in read-only quarantine.",
|
|
"github_intake", RiskLevel.READ, Availability.PLANNED, "opax-mcp", None,
|
|
("authenticated_user", "github_intake_read"), False, None, True, False, False,
|
|
("explicitly_requested_repository",), "explicit_read_only_quarantine",
|
|
),
|
|
_capability(
|
|
"gitea.create_issue", "Create Gitea issue",
|
|
"Create an approved Gitea issue.", "gitea", RiskLevel.WRITE,
|
|
Availability.PLANNED, "opax-mcp", "create_issue",
|
|
("authenticated_user", "gitea_write"), True, "exact_repository_title_body", True,
|
|
False, True, ("git.vauco.no",), "internal_authoritative_only",
|
|
),
|
|
_capability(
|
|
"gitea.push_change", "Push approved Gitea change",
|
|
"Push an approved change to Gitea.", "gitea", RiskLevel.WRITE,
|
|
Availability.PLANNED, "opax-mcp", "push_file",
|
|
("authenticated_user", "gitea_write"), True,
|
|
"exact_repository_branch_path_content_sha", True, True, True,
|
|
("git.vauco.no",), "internal_authoritative_only",
|
|
),
|
|
_capability(
|
|
"cloudbuild.trigger", "Trigger approved Cloud Build",
|
|
"Trigger an approved Cloud Build.", "cloudbuild", RiskLevel.HIGH_IMPACT,
|
|
Availability.PLANNED, "opax-mcp", "trigger_build",
|
|
("authenticated_user", "cloudbuild_execute"), True,
|
|
"exact_build_source_config_substitutions", True, False, True,
|
|
("propane-will-491900-m5",), "internal_project_only",
|
|
),
|
|
_capability(
|
|
"cloudrun.deploy_digest", "Deploy approved Cloud Run image digest",
|
|
"Deploy an approved immutable image digest to Cloud Run.", "cloudrun",
|
|
RiskLevel.HIGH_IMPACT, Availability.PLANNED, "opax-mcp", "build_and_deploy_service",
|
|
("authenticated_user", "cloudrun_deploy"), True,
|
|
"exact_service_region_image_digest_rollback_revision", True, True, True,
|
|
("propane-will-491900-m5", "us-central1"), "internal_project_only",
|
|
),
|
|
_capability(
|
|
"emma.update_ui", "Update Emma UI",
|
|
"Update Emma UI through the approved self-update flow.", "self_update",
|
|
RiskLevel.HIGH_IMPACT, Availability.PLANNED, "opax-mcp", None,
|
|
("authenticated_user", "emma_self_update"), True,
|
|
"exact_repository_branch_diff_tests_image_digest_service", True, True, True,
|
|
("git.vauco.no", "opax.vauco.no"), "internal_authoritative_only",
|
|
),
|
|
_capability(
|
|
"emma.update_backend", "Update Emma backend",
|
|
"Update Emma backend through the approved self-update flow.", "self_update",
|
|
RiskLevel.HIGH_IMPACT, Availability.PLANNED, "opax-mcp", None,
|
|
("authenticated_user", "emma_self_update"), True,
|
|
"exact_repository_branch_diff_tests_image_digest_service", True, True, True,
|
|
("git.vauco.no", "opax-mcp"), "internal_authoritative_only",
|
|
),
|
|
_capability(
|
|
"emma.update_model_config", "Update Emma model configuration",
|
|
"Update model configuration through the approved self-update flow.", "self_update",
|
|
RiskLevel.HIGH_IMPACT, Availability.PLANNED, "opax-mcp", None,
|
|
("authenticated_user", "emma_self_update"), True,
|
|
"exact_model_config_diff_tests_target", True, True, True,
|
|
("opax-mcp", "os-vauco-agent"), "internal_project_only",
|
|
),
|
|
_capability(
|
|
"emma.cli", "Emma CLI",
|
|
"Use Emma through a CLI governed by the same policy as the UI.", "interface",
|
|
RiskLevel.READ, Availability.PLANNED, "opax-mcp", None,
|
|
("authenticated_user",), False, None, True, False, False,
|
|
("approved_vauco_operator_environment",), "same_policy_as_emma_ui",
|
|
),
|
|
_capability(
|
|
"terminal.arbitrary_shell", "Arbitrary terminal shell",
|
|
"Arbitrary terminal execution is prohibited.", "terminal", RiskLevel.FORBIDDEN,
|
|
Availability.FORBIDDEN, "none", None, (), False, None, True, False, True,
|
|
(), "prohibited",
|
|
),
|
|
)
|
|
|
|
|
|
CAPABILITIES: Mapping[str, Capability] = MappingProxyType(
|
|
{capability.id: capability for capability in _CAPABILITIES_TUPLE}
|
|
)
|
|
|
|
|
|
def get_capability(capability_id: str) -> Capability | None:
|
|
return CAPABILITIES.get(capability_id)
|
|
|
|
|
|
def list_capabilities() -> Tuple[Capability, ...]:
|
|
return _CAPABILITIES_TUPLE
|
|
|
|
|
|
def list_active_capabilities() -> Tuple[Capability, ...]:
|
|
return tuple(
|
|
capability
|
|
for capability in _CAPABILITIES_TUPLE
|
|
if capability.availability == Availability.ACTIVE
|
|
)
|