openenv/echo_env
6
1"""Check results and the validation report.2 3The report is the cross-operator contract: schema-versioned JSON embedding the4normalized manifest verbatim. Local-lane reports contain only local-lane check ids —5an author is never shown a check they cannot red-to-green. Hub and statistical check6ids are reserved in this schema so operator reports and local reports share it.7"""8 9from pathlib import Path10from typing import Any, Literal11 12from pydantic import BaseModel, ConfigDict, Field13 14from .manifest import NormalizedManifest, NormalizedManifestV215from .types import CheckStatus, Lane, Level, SignatureKind, Verdict16 17 18class CheckResult(BaseModel):19 """20 Outcome of one check, as emitted by its grader.21 22 Attributes:23 check_id (`str`):24 Stable, policy-addressed id. Local runs use `static.*`/`runtime.*`/25 `semantic.*`; the `hub.*` and `statistical.*` namespaces are reserved for26 operator lanes.27 status ([`~openenv.validation.types.CheckStatus`]):28 The grader's finding. Severity is assigned by the policy, never here.29 measured (`dict[str, Any]`, *optional*):30 Measured values, e.g. `{"oracle_reward": 0.98, "declared_tolerance": 0.05}`.31 evidence (`list[str]`, *optional*):32 Human-readable, credential-safe evidence lines.33 remediation (`str`, *optional*):34 What the author changes to go green.35 duration_s (`float`):36 Wall-clock time this check took.37 """38 39 model_config = ConfigDict(extra="forbid")40 41 check_id: str = Field(pattern=r"^[a-z_]+\.[a-z_]+$")42 status: CheckStatus43 measured: dict[str, Any] = Field(default_factory=dict)44 evidence: list[str] = Field(default_factory=list)45 remediation: str | None = None46 duration_s: float = Field(ge=0.0)47 48 49class ValidationReport(BaseModel):50 """51 One report per validation run, maximum information per run.52 53 Pin `policy_version` and a local run reproduces the hub verdict, modulo hub-lane54 checks.55 56 `manifest` is `None` only when the package's declarations failed the manifest57 schema. The report then carries the `static.manifest` FAIL explaining why.58 """59 60 model_config = ConfigDict(extra="forbid")61 62 report_schema_version: Literal["1"]63 target: str64 source_digest: str65 signature: SignatureKind66 manifest: NormalizedManifest | None67 policy_version: str68 lane: Lane69 levels_run: list[Level]70 results: list[CheckResult]71 verdict: Verdict72 73 74class ValidationReportV2(ValidationReport):75 """76 Report version 2 preserves runtime declarations and parse-failure reporting.77 78 A runtime request may target a version 1 package without an execution binding,79 or fail before producing any manifest. Both remain representable so the report80 can explain the unmet prerequisite or manifest error.81 """82 83 report_schema_version: Literal["2"]84 manifest: NormalizedManifestV2 | NormalizedManifest | None85 86 87def write_report(report: ValidationReport, path: Path | None = None) -> str:88 """89 Serialize a validation report to schema-versioned JSON.90 91 Args:92 report ([`~openenv.validation.report.ValidationReport`]):93 The completed report.94 path (`Path`, *optional*):95 When set, the JSON is also written to this file.96 97 Returns:98 `str`: the JSON payload, without a trailing newline.99 """100 payload = report.model_dump_json(indent=2)101 if path is not None:102 path.write_text(payload + "\n")103 return payload104 