"""Pydantic models for delegation lifecycle. Originally from llm-principal-broker (GCAP-SPEC-LLM-PRINCIPAL-BROKER-0001 §3, §8). Absorbed into fastapi-gsap as the delegations submodule so that the lifecycle bookkeeping shares process and database with the AC issuance endpoints. The previous standalone service made an HTTP call back to GSAP on every delegation creation; now it is an in-process function call. """ from pydantic import BaseModel, Field from typing import Optional from enum import Enum class DelegationStatus(str, Enum): REQUESTED = "requested" ACTIVE = "active" EXPIRED = "expired" REVOKED = "revoked" class DelegationScope(BaseModel): inherit_corpus: bool = True inherit_contexts: bool = True capability_ceiling: str = "CAP_MUTATE" ceremony_required_for: list[str] = Field( default_factory=lambda: ["delete", "destroy", "drop"] ) prohibited_commands: list[str] = Field(default_factory=list) max_ttl_minutes: int = 60 max_commands: int = 500 class DelegationRequest(BaseModel): """POST /delegations/ request body — §8.1.""" delegator_ac_id: str agent_type: str = "claude-code" agent_model: Optional[str] = None scope: Optional[DelegationScope] = None accord_template: str = "ai-delegation-standard" class AgentPrincipal(BaseModel): did: str keycloak_client_id: str display_name: str class DelegationResponse(BaseModel): """POST /delegations/ response — §3.2.""" delegation_id: str agent_principal: AgentPrincipal delegated_ac: dict agent_token: str expires_at: str max_commands: int chronicle_cid: Optional[str] = None class DelegationInfo(BaseModel): """GET /delegations/{id} response — §8.3.""" delegation_id: str status: DelegationStatus agent_did: str agent_type: str delegator_did: str commands_executed: int commands_remaining: int ttl_remaining_seconds: int created_at: str expires_at: str class RevokeRequest(BaseModel): reason: str = "manual_revocation" class RevokeResponse(BaseModel): delegation_id: str status: str = "revoked" reason: str chronicle_cid: Optional[str] = None class ActiveDelegation(BaseModel): delegation_id: str agent_type: str delegator: str commands_executed: int ttl_remaining_seconds: int status: str class AgentListResponse(BaseModel): active_delegations: list[ActiveDelegation] total_active: int