Files
aios/active-runtime/app/aios_governed_local_writer_service.py
T

932 lines
42 KiB
Python

"""Unix-socket service for governed local writer operations."""
from __future__ import annotations
import json
import hashlib
import argparse
import importlib.util
import os
import re
import socket
import subprocess
import sys
import tempfile
import uuid
from dataclasses import dataclass, field
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Callable, Mapping, Protocol
from governed_local_writer import (
AppendCommitRequest,
AuthorizationError,
BranchPolicy,
CreateBranchRequest,
GovernedAuthorization,
PeerIdentity,
PRINCIPAL,
TASK_ID,
extract_peer_identity,
contains_secret_like_content,
load_authorization_file,
validate_file_changes,
)
class ExistingGitOpsHandler:
"""Delegate repository mutations to the installed GitOps handler seam."""
def __init__(
self,
*,
workspace_by_branch: Mapping[str, str | os.PathLike[str]],
bare_repo: str | os.PathLike[str],
api_source: str | os.PathLike[str],
) -> None:
self.workspace_by_branch = {str(k): Path(v) for k, v in workspace_by_branch.items()}
self.bare_repo = Path(bare_repo)
self.api_source = Path(api_source)
@staticmethod
def _restore_env(previous: Mapping[str, str | None]) -> None:
for key, value in previous.items():
if value is None:
os.environ.pop(key, None)
else:
os.environ[key] = value
def _load_api(self, workspace: Path):
if not self.api_source.is_file() or self.api_source.is_symlink():
raise RuntimeError("installed GitOps handler source is unavailable")
keys = (
"AIOS_GITOPS_WORKSPACE",
"AIOS_GITOPS_BARE_REPO",
"AIOS_GITOPS_WRITES_ENABLED",
"PYTHONDONTWRITEBYTECODE",
"GIT_CONFIG_COUNT",
"GIT_CONFIG_KEY_0",
"GIT_CONFIG_VALUE_0",
"GIT_CONFIG_KEY_1",
"GIT_CONFIG_VALUE_1",
)
previous = {key: os.environ.get(key) for key in keys}
os.environ.update(
{
"AIOS_GITOPS_WORKSPACE": str(workspace),
"AIOS_GITOPS_BARE_REPO": str(self.bare_repo),
"AIOS_GITOPS_WRITES_ENABLED": "true",
"PYTHONDONTWRITEBYTECODE": "1",
"GIT_CONFIG_COUNT": "2",
"GIT_CONFIG_KEY_0": "safe.directory",
"GIT_CONFIG_VALUE_0": str(workspace),
"GIT_CONFIG_KEY_1": "safe.directory",
"GIT_CONFIG_VALUE_1": str(self.bare_repo),
}
)
module_name = f"_governed_gitops_api_{uuid.uuid4().hex}"
try:
spec = importlib.util.spec_from_file_location(module_name, self.api_source)
if spec is None or spec.loader is None:
raise RuntimeError("unable to load installed GitOps handler")
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
decision = module.evaluate_git_write(module.WS)
if not decision.allowed:
raise RuntimeError("existing GitOps write gate denied bootstrap")
return module, previous, module_name
except Exception:
sys.modules.pop(module_name, None)
self._restore_env(previous)
raise
def _workspace(self, branch: str) -> Path:
workspace = self.workspace_by_branch.get(branch)
if workspace is None or not workspace.is_dir():
raise RuntimeError("branch workspace is not authorized")
return workspace
@staticmethod
def _git(workspace: Path, args: list[str]) -> str:
result = subprocess.run(
["git", *args], cwd=workspace, text=True, capture_output=True, check=False
)
if result.returncode != 0:
raise RuntimeError("governed handler git probe failed")
return result.stdout.strip()
def create_branch(self, request: CreateBranchRequest) -> Mapping[str, object]:
workspace = self._workspace(request.branch)
# A prior handler call may have completed the fast-forward sync before
# the process observed a post-commit error. Reconcile only an exact,
# metadata-only result; never overwrite or move an existing ref here.
try:
existing = self._git(
workspace,
[
"--git-dir",
str(self.bare_repo),
"rev-parse",
f"refs/heads/{request.branch}",
],
)
except RuntimeError:
existing = ""
if existing:
parent = self._git(workspace, ["--git-dir", str(self.bare_repo), "rev-parse", f"{existing}^1"])
changed = self._git(
workspace,
[
"--git-dir",
str(self.bare_repo),
"diff-tree",
"--no-commit-id",
"--name-only",
"-r",
existing,
],
).splitlines()
safe_branch = re.sub(r"[^A-Za-z0-9_.-]+", "-", request.branch).strip("-")
if parent != request.base_oid or changed != [f"patches/{safe_branch}.branch.json"]:
raise RuntimeError("existing branch is not an exact metadata-only bootstrap")
return {"head_oid": existing, "parent_oid": parent, "handler_status": "reconciled"}
module, previous, module_name = self._load_api(workspace)
phase = "loaded"
try:
phase = "verify_base"
parent = self._git(
workspace,
["--git-dir", str(self.bare_repo), "rev-parse", "refs/heads/main"],
)
if parent != request.base_oid:
raise RuntimeError("authorized base OID drift")
phase = "checkout"
module.checkout(request.branch, base=request.base_oid, create=True)
phase = "write_metadata"
safe_branch = re.sub(r"[^A-Za-z0-9_.-]+", "-", request.branch).strip("-")
metadata_path = f"patches/{safe_branch}.branch.json"
module.write_json(
metadata_path,
{
"schema": "aios.governed-local-writer-bootstrap.v1",
"task_id": TASK_ID,
"principal": PRINCIPAL,
"branch": request.branch,
"parent_oid": request.base_oid,
"authorization_sha256": request.authorization_digest,
},
)
phase = "commit_and_sync"
result = module.commit(
[metadata_path], "chore(governance): bootstrap repair lease branch"
)
head_oid = self._git(workspace, ["rev-parse", "HEAD"])
first_parent = self._git(workspace, ["rev-parse", "HEAD^1"])
if first_parent != request.base_oid or (request.head_oid and head_oid != request.head_oid):
raise RuntimeError("bootstrap branch lineage check failed")
return {
"head_oid": head_oid,
"parent_oid": first_parent,
"handler_status": str(result.get("status")),
}
except Exception as exc:
raise RuntimeError(f"handler_phase={phase};error={exc.__class__.__name__}") from exc
finally:
sys.modules.pop(module_name, None)
self._restore_env(previous)
def append_commit(self, request: AppendCommitRequest) -> Mapping[str, object]:
workspace = self._workspace(request.branch)
module, previous, module_name = self._load_api(workspace)
phase = "loaded"
try:
phase = "verify_head"
current = self._git(workspace, ["rev-parse", "HEAD"])
if current != request.expected_head_oid:
raise RuntimeError("branch head advanced or is stale")
phase = "checkout"
module.checkout(request.branch, base=request.expected_head_oid, create=False)
phase = "write_files"
paths: list[str] = []
for change in request.changes:
paths.append(module.write_file(change.path, change.content))
phase = "commit_and_sync"
result = module.commit(paths, request.commit_message)
head_oid = self._git(workspace, ["rev-parse", "HEAD"])
first_parent = self._git(workspace, ["rev-parse", "HEAD^1"])
if first_parent != request.expected_head_oid or head_oid == first_parent:
raise RuntimeError("append commit lineage check failed")
return {
"head_oid": head_oid,
"parent_oid": first_parent,
"handler_status": str(result.get("status")),
}
except Exception as exc:
raise RuntimeError(f"handler_phase={phase};error={exc.__class__.__name__}") from exc
finally:
sys.modules.pop(module_name, None)
self._restore_env(previous)
class GovernedWriterHandler(Protocol):
"""Small adapter interface for real writer backend handlers."""
def create_branch(self, request: CreateBranchRequest) -> Mapping[str, object]:
"""Create a branch using internal repo services."""
def append_commit(self, request: AppendCommitRequest) -> Mapping[str, object]:
"""Append a commit using internal repo services."""
class AuditSink(Protocol):
"""Pluggable sink for sanitized audit records."""
def append(self, record: "AuditRecord") -> None:
"""Persist one audit record."""
@dataclass
class AuditRecord:
"""Sanitized audit log entry."""
authorization_digest: str
peer_pid: int
peer_uid: int
peer_gid: int
peer_executable: str | None
timestamp: datetime
operation: str
branch: str
result: str
class InMemoryAuditSink:
"""Simple in-memory audit log used by tests."""
def __init__(self) -> None:
self.records: list[AuditRecord] = []
def append(self, record: AuditRecord) -> None:
self.records.append(record)
@dataclass
class _AuthorizationState:
"""Tracks one-shot operation consumption."""
create_done: set[str] = field(default_factory=set)
append_done: set[str] = field(default_factory=set)
consumed: bool = False
class GovernedLocalWriterService:
"""Policy-aware AF_UNIX service that calls an injected handler."""
def __init__(
self,
socket_path: str | os.PathLike[str],
authorization: GovernedAuthorization,
handler: GovernedWriterHandler,
*,
audit_sink: AuditSink | None = None,
peer_identity_fn: Callable[[socket.socket], PeerIdentity] | None = None,
state_path: str | os.PathLike[str] | None = None,
) -> None:
self.socket_path = Path(socket_path)
self.authorization = authorization
self.handler = handler
self.peer_identity_fn = peer_identity_fn or extract_peer_identity
self.state = _AuthorizationState()
self.audit_sink = audit_sink or InMemoryAuditSink()
self.state_path = Path(state_path) if state_path is not None else None
self._load_state()
def _load_state(self) -> None:
"""Restore one-shot state without restoring request or secret material."""
if self.state_path is None or not self.state_path.exists():
return
try:
raw = json.loads(self.state_path.read_text(encoding="utf-8"))
if not isinstance(raw, dict):
raise ValueError("state must be an object")
if raw.get("authorization_sha256") != self.authorization.authorization_sha256:
raise ValueError("state authorization digest mismatch")
self.state.create_done = {str(v) for v in raw.get("create_done", [])}
self.state.append_done = {str(v) for v in raw.get("append_done", [])}
self.state.consumed = bool(raw.get("consumed", False))
except (OSError, ValueError, TypeError, json.JSONDecodeError) as exc:
raise AuthorizationError("authorization state is invalid") from exc
def _persist_state(self) -> None:
if self.state_path is None:
return
self.state_path.parent.mkdir(parents=True, exist_ok=True)
payload = {
"authorization_sha256": self.authorization.authorization_sha256,
"create_done": sorted(self.state.create_done),
"append_done": sorted(self.state.append_done),
"consumed": self.state.consumed,
}
fd, temp_name = tempfile.mkstemp(prefix=".writer-state-", dir=self.state_path.parent)
try:
os.fchmod(fd, 0o600)
with os.fdopen(fd, "w", encoding="utf-8") as stream:
json.dump(payload, stream, sort_keys=True, separators=(",", ":"))
stream.write("\n")
os.replace(temp_name, self.state_path)
os.chmod(self.state_path, 0o600)
finally:
if os.path.exists(temp_name):
os.unlink(temp_name)
def _new_audit(self, peer: PeerIdentity, operation: str, branch: str, result: str) -> None:
self.audit_sink.append(
AuditRecord(
authorization_digest=self.authorization.authorization_sha256,
peer_pid=peer.pid,
peer_uid=peer.uid,
peer_gid=peer.gid,
peer_executable=peer.executable,
timestamp=datetime.now(tz=timezone.utc),
operation=operation,
branch=branch,
result=result,
)
)
def _require_request_field(self, request: Mapping[str, Any], field_name: str) -> str:
value = request.get(field_name)
if not isinstance(value, str) or not value:
raise AuthorizationError(f"{field_name} must be a non-empty string")
return value
def _branch_policy(self, branch: str) -> BranchPolicy:
policy = self.authorization.branch_operations.get(branch)
if policy is None:
raise AuthorizationError("branch is not authorized")
return policy
def _ensure_not_consumed(self) -> None:
if self.state.consumed:
raise AuthorizationError("authorization consumed")
if datetime.now(tz=timezone.utc) >= self.authorization.expires_at:
raise AuthorizationError("authorization expired")
def _mark_success(self, op: str, branch: str) -> None:
if op == "create_branch":
self.state.create_done.add(branch)
elif op == "append_commit":
self.state.append_done.add(branch)
if self.state.create_done.issuperset(self.authorization.create_branches) and self.state.append_done.issuperset(
self.authorization.append_branches
):
self.state.consumed = True
self._persist_state()
def _validate_request(self, request: Mapping[str, Any]) -> dict[str, Any]:
task_id = self._require_request_field(request, "task_id")
if task_id != TASK_ID:
raise AuthorizationError("invalid task_id")
principal = self._require_request_field(request, "principal")
if principal != PRINCIPAL:
raise AuthorizationError("invalid principal")
operation = self._require_request_field(request, "op")
if operation not in {"create_branch", "append_commit"}:
raise AuthorizationError("unsupported operation")
if operation in self.authorization.denied_operations:
raise AuthorizationError("operation denied by policy")
branch = self._require_request_field(request, "branch")
self._ensure_not_consumed()
policy = self._branch_policy(branch)
if operation == "create_branch":
if policy.create_branch is None:
raise AuthorizationError("branch does not allow create_branch")
if branch in self.state.create_done:
raise AuthorizationError("create_branch already used for this branch")
base_oid = self._require_request_field(request, "base_oid")
raw_head_oid = request.get("head_oid")
if raw_head_oid is not None and (not isinstance(raw_head_oid, str) or not raw_head_oid):
raise AuthorizationError("head_oid must be a non-empty string when supplied")
head_oid = str(raw_head_oid) if raw_head_oid is not None else None
if base_oid != policy.create_branch.base_oid:
raise AuthorizationError("base_oid mismatch")
if policy.create_branch.head_oid is not None and head_oid != policy.create_branch.head_oid:
raise AuthorizationError("head_oid mismatch")
return {
"operation": operation,
"branch": branch,
"base_oid": base_oid,
"head_oid": head_oid,
}
if policy.append_commit is None:
raise AuthorizationError("branch does not allow append_commit")
if policy.create_branch is not None and branch not in self.state.create_done:
raise AuthorizationError("append_commit requires prior successful create_branch")
if branch in self.state.append_done:
raise AuthorizationError("append_commit already used for this branch")
expected_head = policy.append_commit.expected_head_oid
if "expected_head_oid" in request:
supplied_head = self._require_request_field(request, "expected_head_oid")
elif "current_head_oid" in request:
supplied_head = self._require_request_field(request, "current_head_oid")
else:
raise AuthorizationError("expected_head_oid or current_head_oid required")
if not re.fullmatch(r"[0-9a-fA-F]{40}", supplied_head):
raise AuthorizationError("head check must be a full commit OID")
if expected_head is not None and supplied_head != expected_head:
raise AuthorizationError("head check failed")
if request.get("force") is True or request.get("non_fast_forward") is True:
raise AuthorizationError("non-fast-forward operations are not allowed")
if request.get("history_rewrite") is True:
raise AuthorizationError("history rewrite is not allowed")
parent_oids = request.get("parent_oids")
if parent_oids is not None:
if not isinstance(parent_oids, list) or parent_oids != [supplied_head]:
raise AuthorizationError("parent_oids must contain exactly expected_head_oid")
changes = request.get("changes")
if not isinstance(changes, list):
raise AuthorizationError("changes must be a list")
validated_changes = validate_file_changes(changes, policy.append_commit.allowed_paths)
commit_message = request.get("commit_message", "chore(governance): append governed commit")
if not isinstance(commit_message, str) or not commit_message.strip() or len(commit_message) > 200:
raise AuthorizationError("commit_message must be a short non-empty string")
if "\n" in commit_message or "\r" in commit_message or contains_secret_like_content(commit_message):
raise AuthorizationError("commit_message failed policy")
return {
"operation": operation,
"branch": branch,
"expected_head_oid": supplied_head,
"changes": validated_changes,
"commit_message": commit_message.strip(),
}
def process_request(self, raw_request: Mapping[str, Any], peer: PeerIdentity) -> Mapping[str, Any]:
"""Run one request through policy checks and handler adapter."""
operation = raw_request.get("op") if isinstance(raw_request.get("op"), str) else "unknown"
branch = raw_request.get("branch") if isinstance(raw_request.get("branch"), str) else ""
try:
details = self._validate_request(raw_request)
operation = str(details["operation"])
branch = str(details["branch"])
if operation == "create_branch":
self.handler.create_branch(
CreateBranchRequest(
branch=branch,
base_oid=str(details["base_oid"]),
head_oid=(
str(details["head_oid"])
if details.get("head_oid") is not None
else None
),
authorization_digest=self.authorization.authorization_sha256,
)
)
self._mark_success("create_branch", branch)
self._new_audit(peer, operation, branch, "ok")
return {
"status": "ok",
"operation": operation,
"branch": branch,
"result": "applied",
}
self.handler.append_commit(
AppendCommitRequest(
branch=branch,
expected_head_oid=str(details["expected_head_oid"]),
changes=tuple(details["changes"]),
authorization_digest=self.authorization.authorization_sha256,
commit_message=str(details["commit_message"]),
)
)
self._mark_success("append_commit", branch)
self._new_audit(peer, operation, branch, "ok")
return {
"status": "ok",
"operation": operation,
"branch": branch,
"result": "applied",
}
except Exception as error:
self._new_audit(peer, operation or "unknown", branch, f"error:{error.__class__.__name__}")
if isinstance(error, PermissionError):
code = "permission_denied"
elif isinstance(error, AuthorizationError):
code = "request_denied"
else:
code = "handler_failed"
if code == "handler_failed" and str(error).startswith("handler_phase="):
code = str(error)
return {
"status": "error",
"operation": operation or "unknown",
"branch": branch,
"error": code,
}
def _write_json(self, connection: socket.socket, payload: Mapping[str, Any]) -> None:
connection.sendall((json.dumps(payload) + "\n").encode("utf-8"))
def _handle_client(self, connection: socket.socket) -> None:
with connection:
try:
peer = self.peer_identity_fn(connection)
except Exception:
self._write_json(
connection,
{
"status": "error",
"operation": "connection",
"branch": "",
"error": "peer identity validation failed",
},
)
return
with connection.makefile("r", encoding="utf-8") as stream:
for raw_line in stream:
line = raw_line.strip()
if not line:
continue
try:
request = json.loads(line)
except json.JSONDecodeError:
self._write_json(
connection,
{
"status": "error",
"operation": "request",
"branch": "",
"error": "invalid json",
},
)
continue
if not isinstance(request, Mapping):
self._write_json(
connection,
{
"status": "error",
"operation": "request",
"branch": "",
"error": "request must be a JSON object",
},
)
continue
self._write_json(connection, self.process_request(request, peer))
def _bind_socket(self) -> socket.socket:
if self.socket_path.exists():
raise RuntimeError("governed writer socket already exists")
parent = self.socket_path.parent
if not parent.is_dir():
raise RuntimeError("governed writer socket parent is missing")
if parent.is_symlink():
raise RuntimeError("governed writer socket parent must not be a symlink")
server = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM)
server.bind(str(self.socket_path))
os.chmod(self.socket_path, 0o600)
server.listen(16)
return server
def serve(self) -> None:
"""Serve newline-delimited JSON over a filesystem AF_UNIX socket."""
server = self._bind_socket()
try:
while True:
connection, _ = server.accept()
self._handle_client(connection)
finally:
server.close()
if self.socket_path.exists():
self.socket_path.unlink()
class JsonAuditSink:
"""Append-only root-owned audit sink containing no request payloads."""
def __init__(self, path: str | os.PathLike[str]) -> None:
self.path = Path(path)
self.path.parent.mkdir(parents=True, exist_ok=True)
def append(self, record: AuditRecord) -> None:
payload = {
"authorization_sha256": record.authorization_digest,
"peer_pid": record.peer_pid,
"peer_uid": record.peer_uid,
"peer_gid": record.peer_gid,
"peer_executable": record.peer_executable,
"timestamp": record.timestamp.isoformat(),
"operation": record.operation,
"branch": record.branch,
"result": record.result,
}
line = (json.dumps(payload, sort_keys=True, separators=(",", ":")) + "\n").encode("utf-8")
fd = os.open(self.path, os.O_WRONLY | os.O_CREAT | os.O_APPEND, 0o600)
try:
os.fchmod(fd, 0o600)
os.write(fd, line)
finally:
os.close(fd)
# V2R1C6 durable receipt overlay. This subclasses the original root-only
# writer in-place so the existing AF_UNIX/SO_PEERCRED and handler policy remain
# the only mutation path.
_LegacyGovernedLocalWriterService = GovernedLocalWriterService
class GovernedLocalWriterService(_LegacyGovernedLocalWriterService):
"""Existing writer with durable request receipts and safe recovery."""
def _load_state(self) -> None:
super()._load_state()
self.state.receipts = {}
if self.state_path is None or not self.state_path.exists():
return
raw = json.loads(self.state_path.read_text(encoding="utf-8"))
if not isinstance(raw, dict):
raise AuthorizationError("authorization state is invalid")
receipts = raw.get("receipts", {})
if not isinstance(receipts, dict):
raise AuthorizationError("authorization receipts are invalid")
self.state.receipts = {
str(key): dict(value)
for key, value in receipts.items()
if isinstance(value, dict)
}
def _persist_state(self) -> None:
if self.state_path is None:
return
self.state_path.parent.mkdir(parents=True, exist_ok=True)
payload = {
"authorization_sha256": self.authorization.authorization_sha256,
"create_done": sorted(self.state.create_done),
"append_done": sorted(self.state.append_done),
"consumed": bool(self.state.consumed),
"receipts": self.state.receipts,
}
fd, temp_name = tempfile.mkstemp(prefix=".writer-state-", dir=self.state_path.parent)
try:
os.fchmod(fd, 0o600)
with os.fdopen(fd, "w", encoding="utf-8") as stream:
json.dump(payload, stream, sort_keys=True, separators=(",", ":"))
stream.write("\n")
os.replace(temp_name, self.state_path)
os.chmod(self.state_path, 0o600)
finally:
if os.path.exists(temp_name):
os.unlink(temp_name)
def _request_identity(self, request: Mapping[str, Any]) -> dict[str, str]:
canonical = json.dumps(dict(request), sort_keys=True, separators=(",", ":"), ensure_ascii=True)
fallback = hashlib.sha256(canonical.encode("utf-8")).hexdigest()
request_id = request.get("request_id")
idempotency_key = request.get("idempotency_key")
request_id = request_id.strip() if isinstance(request_id, str) and request_id.strip() else "legacy-" + fallback
idempotency_key = idempotency_key.strip() if isinstance(idempotency_key, str) and idempotency_key.strip() else "legacy-" + fallback
for field_name, value in (("request_id", request_id), ("idempotency_key", idempotency_key)):
if len(value) > 200 or "\n" in value or "\r" in value:
raise AuthorizationError(field_name + " is invalid")
return {
"request_id": request_id,
"idempotency_key": idempotency_key,
"request_fingerprint": fallback,
}
def _find_receipt(self, details: Mapping[str, Any], compare_fingerprint: bool = True):
request_id = str(details["request_id"])
idempotency_key = str(details["idempotency_key"])
fingerprint = str(details.get("request_fingerprint", ""))
for receipt in self.state.receipts.values():
if receipt.get("request_id") == request_id or receipt.get("idempotency_key") == idempotency_key:
if compare_fingerprint and receipt.get("request_fingerprint") != fingerprint:
raise AuthorizationError("idempotency key reused with different request")
return receipt
return None
@staticmethod
def _receipt_response(receipt: Mapping[str, object], status: str = "receipt") -> dict[str, object]:
response = {
"status": status,
"request_id": receipt.get("request_id"),
"idempotency_key": receipt.get("idempotency_key"),
"operation": receipt.get("operation"),
"branch": receipt.get("branch", ""),
"receipt_status": receipt.get("status"),
}
for field_name in ("commit_oid", "final_head", "parent_oid", "audit_sha256", "error_code", "safe_to_retry"):
if field_name in receipt:
response[field_name] = receipt[field_name]
return response
def _new_receipt(self, details: Mapping[str, Any]) -> dict[str, object]:
return {
"request_id": str(details["request_id"]),
"idempotency_key": str(details["idempotency_key"]),
"request_fingerprint": str(details["request_fingerprint"]),
"operation": str(details["operation"]),
"branch": str(details.get("branch", "")),
"expected_head_oid": str(details.get("expected_head_oid", "")),
"status": "accepted",
"created_at": datetime.now(tz=timezone.utc).isoformat(),
"safe_to_retry": False,
}
def _new_audit(self, peer: PeerIdentity, operation: str, branch: str, result: str) -> str:
super()._new_audit(peer, operation, branch, result)
payload = {
"authorization_sha256": self.authorization.authorization_sha256,
"peer_pid": peer.pid,
"peer_uid": peer.uid,
"peer_gid": peer.gid,
"peer_executable": peer.executable,
"operation": operation,
"branch": branch,
"result": result,
}
return hashlib.sha256(json.dumps(payload, sort_keys=True, separators=(",", ":")).encode("utf-8")).hexdigest()
def _mark_success(self, op: str, branch: str) -> None:
if op == "create_branch":
self.state.create_done.add(branch)
elif op in {"append_commit", "append_files", "append_batch"}:
self.state.append_done.add(branch)
# The provisioning grant is one-shot; the task writer lease itself must
# support multiple append receipts for the exact authorized branches.
self.state.consumed = False
self._persist_state()
def _validate_durable(self, raw_request: Mapping[str, Any]) -> dict[str, Any]:
operation = self._require_request_field(raw_request, "op")
identity = self._request_identity(raw_request)
if operation == "query_receipt":
return {"operation": operation, **identity}
if operation == "recover_request":
branch = self._require_request_field(raw_request, "branch")
policy = self._branch_policy(branch)
if policy.append_commit is None:
raise AuthorizationError("branch does not allow recovery")
expected = raw_request.get("expected_head_oid") or policy.append_commit.expected_head_oid
if not isinstance(expected, str) or not re.fullmatch(r"[0-9a-fA-F]{40}", expected):
raise AuthorizationError("recovery requires expected_head_oid")
return {"operation": operation, "branch": branch, "expected_head_oid": expected.lower(), **identity}
if operation not in {"create_branch", "append_commit", "append_files", "append_batch"}:
raise AuthorizationError("unsupported operation")
request = dict(raw_request)
if operation in {"append_files", "append_batch"}:
request["op"] = "append_commit"
if operation in {"append_commit", "append_files", "append_batch"}:
self.state.consumed = False
branch = request.get("branch")
removed = False
dynamic_expected = False
if isinstance(branch, str) and branch in self.state.append_done:
self.state.append_done.remove(branch)
removed = True
policy = self.authorization.branch_operations.get(branch)
if policy is not None and policy.append_commit is not None and policy.append_commit.expected_head_oid is not None:
from governed_local_writer import BranchAppendPolicy, BranchPolicy
self.authorization.branch_operations[branch] = BranchPolicy(create_branch=policy.create_branch, append_commit=BranchAppendPolicy(branch=branch, expected_head_oid=None, allowed_paths=policy.append_commit.allowed_paths))
dynamic_expected = True
try:
details = super()._validate_request(request)
finally:
if dynamic_expected:
policy = self.authorization.branch_operations.get(str(branch))
if policy is not None and policy.append_commit is not None:
from governed_local_writer import BranchAppendPolicy, BranchPolicy
self.authorization.branch_operations[str(branch)] = BranchPolicy(create_branch=policy.create_branch, append_commit=BranchAppendPolicy(branch=str(branch), expected_head_oid=str(raw_request.get("expected_head_oid") or ""), allowed_paths=policy.append_commit.allowed_paths))
if removed:
self.state.append_done.add(str(branch))
details.update(identity)
details["operation"] = operation
return details
def _recover_backend(self, details: Mapping[str, Any]) -> dict[str, object]:
if not hasattr(self.handler, "_workspace") or not hasattr(self.handler, "_git"):
raise RuntimeError("recovery backend unavailable")
workspace = self.handler._workspace(str(details["branch"]))
expected = str(details["expected_head_oid"])
current = self.handler._git(workspace, ["rev-parse", "HEAD"])
if current == expected:
return {"status": "not_started", "final_head": current}
parent = self.handler._git(workspace, ["rev-parse", "HEAD^1"])
if parent != expected:
raise RuntimeError("external branch advance during recovery")
return {"status": "applied", "commit_oid": current, "final_head": current, "parent_oid": parent}
def process_request(self, raw_request: Mapping[str, Any], peer: PeerIdentity) -> Mapping[str, Any]:
operation = raw_request.get("op") if isinstance(raw_request.get("op"), str) else "unknown"
branch = raw_request.get("branch") if isinstance(raw_request.get("branch"), str) else ""
try:
details = self._validate_durable(raw_request)
operation = str(details["operation"])
branch = str(details.get("branch", ""))
if operation == "query_receipt":
receipt = self._find_receipt(details, compare_fingerprint=False)
return self._receipt_response(receipt) if receipt is not None else {"status": "not_found", "request_id": details["request_id"], "idempotency_key": details["idempotency_key"]}
if operation == "recover_request":
receipt = self._find_receipt(details, compare_fingerprint=False)
if receipt is None:
return {"status": "not_found", "request_id": details["request_id"], "idempotency_key": details["idempotency_key"], "safe_to_retry": True}
if receipt.get("status") == "applied":
return self._receipt_response(receipt)
recovered = self._recover_backend(details)
if recovered.get("status") == "applied":
receipt.update({"status": "applied", "commit_oid": recovered.get("commit_oid"), "final_head": recovered.get("final_head"), "parent_oid": recovered.get("parent_oid"), "safe_to_retry": False})
self._mark_success("append_commit", branch)
return self._receipt_response(receipt)
receipt["safe_to_retry"] = True
self._persist_state()
return self._receipt_response(receipt)
receipt = self._find_receipt(details)
if receipt is not None:
return self._receipt_response(receipt)
receipt = self._new_receipt(details)
self.state.receipts[str(details["request_id"])] = receipt
self._persist_state()
if operation == "create_branch":
result = self.handler.create_branch(CreateBranchRequest(branch=branch, base_oid=str(details["base_oid"]), head_oid=str(details["head_oid"]) if details.get("head_oid") is not None else None, authorization_digest=self.authorization.authorization_sha256))
commit_oid = str(result.get("head_oid", ""))
parent_oid = str(result.get("parent_oid", ""))
audit_sha = self._new_audit(peer, operation, branch, "ok")
receipt.update({"status": "applied", "commit_oid": commit_oid, "final_head": commit_oid, "parent_oid": parent_oid, "audit_sha256": audit_sha, "safe_to_retry": False})
self._mark_success("create_branch", branch)
return self._receipt_response(receipt, status="ok") | {"result": "applied"}
result = self.handler.append_commit(AppendCommitRequest(branch=branch, expected_head_oid=str(details["expected_head_oid"]), changes=tuple(details["changes"]), authorization_digest=self.authorization.authorization_sha256, commit_message=str(details["commit_message"])))
commit_oid = str(result.get("head_oid", ""))
parent_oid = str(result.get("parent_oid", ""))
audit_sha = self._new_audit(peer, operation, branch, "ok")
receipt.update({"status": "applied", "commit_oid": commit_oid, "final_head": commit_oid, "parent_oid": parent_oid, "audit_sha256": audit_sha, "safe_to_retry": False})
self._mark_success("append_commit", branch)
return self._receipt_response(receipt, status="ok") | {"result": "applied"}
except Exception as error:
try:
identity = self._request_identity(raw_request)
receipt = self.state.receipts.get(identity["request_id"])
if receipt is not None and receipt.get("status") == "accepted":
receipt.update({"status": "failed", "error_code": error.__class__.__name__, "safe_to_retry": False})
self._persist_state()
except Exception:
pass
self._new_audit(peer, operation, branch, "error:" + error.__class__.__name__)
return {"status": "error", "operation": operation, "branch": branch, "error": "request_denied" if isinstance(error, AuthorizationError) else "handler_failed"}
def _parse_args() -> argparse.Namespace:
parser = argparse.ArgumentParser(description="AIOS governed local writer")
parser.add_argument("--socket", required=True)
parser.add_argument("--authorization", required=True)
parser.add_argument("--state", required=True)
parser.add_argument("--audit", required=True)
parser.add_argument("--repair-branch", required=True)
parser.add_argument("--repair-workspace", required=True)
parser.add_argument("--candidate-branch", required=True)
parser.add_argument("--candidate-workspace", required=True)
parser.add_argument("--bare-repo", required=True)
parser.add_argument("--api-source", required=True)
return parser.parse_args()
def main() -> int:
if hasattr(os, "geteuid") and os.geteuid() != 0:
print("governed local writer requires uid 0", file=sys.stderr)
return 2
args = _parse_args()
authorization = load_authorization_file(args.authorization)
handler = ExistingGitOpsHandler(
workspace_by_branch={
args.repair_branch: args.repair_workspace,
args.candidate_branch: args.candidate_workspace,
},
bare_repo=args.bare_repo,
api_source=args.api_source,
)
service = GovernedLocalWriterService(
args.socket,
authorization,
handler,
audit_sink=JsonAuditSink(args.audit),
state_path=args.state,
)
service.serve()
return 0
if __name__ == "__main__": # pragma: no cover - systemd entrypoint
raise SystemExit(main())