"""Serve a local, synthetic G8 rollback receipt control plane for contract smoke. This harness never mutates a model or deployment. It only proves that the API binds a separately authenticated HTTP executor receipt to the pinned command. It must not be used as production rollback evidence. """ from __future__ import annotations import argparse import hashlib import hmac import json import re from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer from typing import Any TOKEN_HEADER = "X-Vignette-Rollback-Executor-Token" MAX_BODY_BYTES = 65_536 SHA256_PATTERN = re.compile(r"^[a-f0-9]{64}$") REQUIRED_FIELDS = ( "idempotency_key", "rollback_scope", "target_kind", "target_id", "artifact_record_id", "artifact_sha256", ) class HarnessError(ValueError): pass def build_synthetic_receipt(payload: Any) -> dict[str, Any]: if not isinstance(payload, dict): raise HarnessError("request body must be an object") if payload.get("schema_version") != "oas.rollback-executor.v1": raise HarnessError("unsupported rollback executor schema") missing = [key for key in REQUIRED_FIELDS if not payload.get(key)] if missing: raise HarnessError(f"missing required fields: {','.join(missing)}") if payload["rollback_scope"] not in {"model", "runtime"}: raise HarnessError("invalid rollback scope") if payload["target_kind"] not in {"model_change_gate", "release_gate"}: raise HarnessError("invalid target kind") if not SHA256_PATTERN.fullmatch(str(payload["artifact_sha256"])): raise HarnessError("invalid artifact sha256") binding = "|".join(str(payload[key]) for key in REQUIRED_FIELDS) execution_id = f"synthetic-g8-{hashlib.sha256(binding.encode()).hexdigest()[:24]}" return { "schema_version": "oas.rollback-executor.v1", "status": "executed", "execution_id": execution_id, "idempotency_key": payload["idempotency_key"], "rollback_scope": payload["rollback_scope"], "target_kind": payload["target_kind"], "target_id": payload["target_id"], "artifact_record_id": payload["artifact_record_id"], "artifact_sha256": payload["artifact_sha256"], "evidence_refs": [f"audit://synthetic-g8-control-plane/{execution_id}"], } def _handler(*, token: str, mode: str) -> type[BaseHTTPRequestHandler]: class Handler(BaseHTTPRequestHandler): def log_message(self, format: str, *args: object) -> None: return None def _json(self, status: int, payload: dict[str, Any]) -> None: body = json.dumps(payload, separators=(",", ":")).encode("utf-8") self.send_response(status) self.send_header("Content-Type", "application/json") self.send_header("Content-Length", str(len(body))) self.end_headers() self.wfile.write(body) def do_POST(self) -> None: if self.path != "/rollback": self._json(404, {"detail": "not found"}) return presented = self.headers.get(TOKEN_HEADER, "") if not hmac.compare_digest(presented, token): self._json(403, {"detail": "forbidden"}) return try: content_length = int(self.headers.get("Content-Length", "0")) except ValueError: self._json(400, {"detail": "invalid content length"}) return if content_length < 1 or content_length > MAX_BODY_BYTES: self._json(413, {"detail": "request body size rejected"}) return try: payload = json.loads(self.rfile.read(content_length)) receipt = build_synthetic_receipt(payload) except (HarnessError, json.JSONDecodeError) as exc: self._json(422, {"detail": str(exc)}) return if mode == "failed": self._json(503, {"detail": "synthetic executor failure"}) return self._json(200, receipt) return Handler def main() -> None: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--host", default="127.0.0.1") parser.add_argument("--port", type=int, default=18148) parser.add_argument("--token", required=True) parser.add_argument("--mode", choices=("executed", "failed"), default="executed") args = parser.parse_args() if len(args.token) < 32: raise SystemExit("--token must contain at least 32 characters") server = ThreadingHTTPServer( (args.host, args.port), _handler(token=args.token, mode=args.mode) ) print( json.dumps( { "ready": True, "endpoint": f"http://{args.host}:{args.port}/rollback", "mode": args.mode, "synthetic_only": True, }, separators=(",", ":"), ), flush=True, ) server.serve_forever() if __name__ == "__main__": main()