feat(review): add multi-owner contracts and receipts
Assistant: codex Assistant-Model: gpt-5.6-sol Assistant-Session: 01a023c0-a0a3-7c03-b395-5a0d2757214d
This commit is contained in:
parent
52aefe39e4
commit
598f6418e7
13 changed files with 1401 additions and 9 deletions
96
api/schemas/review_contract.py
Normal file
96
api/schemas/review_contract.py
Normal file
|
|
@ -0,0 +1,96 @@
|
|||
import uuid
|
||||
from datetime import datetime
|
||||
from typing import Any, Literal
|
||||
|
||||
from pydantic import BaseModel, ConfigDict, Field
|
||||
|
||||
|
||||
class SourceRef(BaseModel):
|
||||
repo: str = Field(min_length=1, max_length=100)
|
||||
path: str = Field(min_length=1, max_length=1000)
|
||||
revision: str = Field(pattern=r"^[0-9a-f]{40,64}$")
|
||||
|
||||
|
||||
class ReviewContractProject(BaseModel):
|
||||
contract: dict[str, Any]
|
||||
source: SourceRef
|
||||
decision_id: uuid.UUID | None = None
|
||||
workplan_id: uuid.UUID | None = None
|
||||
task_id: uuid.UUID | None = None
|
||||
required_for_decision: bool = False
|
||||
|
||||
|
||||
class ReviewContractRead(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: uuid.UUID
|
||||
contract_key: str
|
||||
schema_version: str
|
||||
contract_digest: str
|
||||
source_repo: str
|
||||
source_path: str
|
||||
source_revision: str
|
||||
document: dict[str, Any]
|
||||
active: bool
|
||||
required_for_decision: bool
|
||||
decision_id: uuid.UUID | None
|
||||
workplan_id: uuid.UUID | None
|
||||
task_id: uuid.UUID | None
|
||||
projected_at: datetime
|
||||
created_at: datetime
|
||||
updated_at: datetime
|
||||
|
||||
|
||||
class ReviewReceiptSubmit(BaseModel):
|
||||
owner_id: str = Field(min_length=1, max_length=160)
|
||||
actor: str = Field(min_length=2, max_length=160)
|
||||
disposition: Literal["approve", "request_changes"]
|
||||
contract_digest: str = Field(pattern=r"^[0-9a-f]{64}$")
|
||||
artifact_hashes: dict[str, str] = Field(default_factory=dict)
|
||||
assertion_ids: list[str] = Field(default_factory=list)
|
||||
checks: list[dict[str, Any]] = Field(default_factory=list)
|
||||
note: str | None = Field(default=None, max_length=2000)
|
||||
source: SourceRef
|
||||
|
||||
|
||||
class ReviewReceiptRead(BaseModel):
|
||||
model_config = ConfigDict(from_attributes=True)
|
||||
id: uuid.UUID
|
||||
contract_id: uuid.UUID
|
||||
owner_id: str
|
||||
actor: str
|
||||
disposition: str
|
||||
contract_digest: str
|
||||
receipt_digest: str
|
||||
artifact_hashes: dict[str, str]
|
||||
assertion_ids: list[str]
|
||||
checks: list[dict[str, Any]]
|
||||
note: str | None
|
||||
source_repo: str
|
||||
source_path: str
|
||||
source_revision: str
|
||||
submitted_at: datetime
|
||||
created_at: datetime
|
||||
|
||||
|
||||
class OwnerReviewState(BaseModel):
|
||||
owner_id: str
|
||||
status: Literal["missing", "approved", "request_changes", "stale"]
|
||||
receipt_id: uuid.UUID | None = None
|
||||
receipt_digest: str | None = None
|
||||
submitted_at: datetime | None = None
|
||||
|
||||
|
||||
class GateReviewState(BaseModel):
|
||||
gate_id: str
|
||||
policy: Literal["all_required"]
|
||||
owners: list[str]
|
||||
satisfied: bool
|
||||
|
||||
|
||||
class ReviewAggregateRead(BaseModel):
|
||||
contract_key: str
|
||||
contract_digest: str
|
||||
satisfied: bool
|
||||
authorizes_execution: Literal[False] = False
|
||||
owners: list[OwnerReviewState]
|
||||
gates: list[GateReviewState]
|
||||
Loading…
Add table
Add a link
Reference in a new issue