M0 e M1 revisados e fixes implementados

This commit is contained in:
Marcos Lohmann
2026-09-14 08:18:53 -03:00
parent 439f60598e
commit f3efcc3414
72 changed files with 4831 additions and 128 deletions

View File

@@ -0,0 +1,52 @@
"""Approval request contract (EP-14-T01, README.md §26).
Out-of-band, bound to the *exact* operation it was requested for (not just
the tool name), with an expiry and single-use semantics -- so an approval
granted for one call can never be replayed against a different one (same
tool, different arguments) or reused twice (README.md §46, "approval
replay").
"""
from __future__ import annotations
import hashlib
import json
from datetime import UTC, datetime
from typing import Any, Literal
from uuid import uuid4
from pydantic import BaseModel, Field
def compute_operation_hash(*, client_profile: str, tool: str, arguments: dict[str, Any]) -> str:
"""Binds an approval to one exact (client_profile, tool, arguments) triple.
Canonical JSON (sorted keys) so the same logical call always hashes the
same way regardless of dict insertion order.
"""
canonical = json.dumps(
{"client_profile": client_profile, "tool": tool, "arguments": arguments},
sort_keys=True,
default=str,
)
return hashlib.sha256(canonical.encode("utf-8")).hexdigest()
class ApprovalRequest(BaseModel):
approval_id: str = Field(default_factory=lambda: str(uuid4()))
operation_hash: str
client_profile: str
tool: str
arguments_summary: dict[str, Any]
"""A copy of the relevant arguments for an approver to review -- README.md
§26 ("com resumo dos argumentos relevantes"). Not redacted in this RI;
a production deployment would apply the same PII-minimization rules as
audit logging (README.md §27)."""
reason_code: str
requested_at: datetime = Field(default_factory=lambda: datetime.now(UTC))
expires_at: datetime
status: Literal["pending", "granted", "denied", "consumed"] = "pending"
def is_expired(self, *, now: datetime | None = None) -> bool:
return (now or datetime.now(UTC)) >= self.expires_at