Compare commits

..
Author SHA1 Message Date
Codex Governance Request 57697d81cf governance: scope Gitea 1.22 token-row revocation 2026-08-01 09:29:23 +08:00
Codex Governance Request 39c97d4f7f governance: revoke task tokens through Gitea API 2026-08-01 09:20:59 +08:00
Codex Governance Request 649e25a668 governance: bind sweeper to per-task audit key 2026-08-01 09:17:26 +08:00
Codex Governance Request fcfd841a2d governance: isolate grant signer and auto-revoke tokens 2026-08-01 09:12:50 +08:00
Codex Governance Request 1a7d62c755 governance: harden task grant and evidence binding 2026-08-01 09:03:40 +08:00
Codex Governance Request 61c8cf3ca7 governance: add task-scoped status and ff-only merge bootstrap 2026-08-01 08:50:27 +08:00
codex 8814dff202 Merge pull request '[TASK SCOPED GOVERNANCE BOOTSTRAP RENEWAL] AIOS Two-Stage Owner Campaign Phase A' (#35) from governance/request/two-stage-owner-campaign-v2-phase-a-renewal-20260731T081147Z into governance/approvals 2026-07-31 17:35:54 +08:00
Codex Governance Request ff6743e851 governance: renew two-stage phase-a activation window
aios/branch-protection PR35 Phase A PASS evidence_sha256=47068a6193db3a257d4af7d7c03e5b29e6ab3b7b146e262efb05e704b158bdfc
aios/evidence-closure PR35 Phase A PASS evidence_sha256=247b155c55a47addee9485e9005da7e0069c0c1c5d977e45dadb3f7da9caf514
aios/secret-scan PR35 Phase A PASS evidence_sha256=e9d0646d237cb0e5ee0456e778571ea81f470b621a5317d37c510804332a2672
aios/state-machine PR35 Phase A PASS evidence_sha256=c14af062600f46b708124c854ad1c2aaad67ec47dd76caca8ee1ae71b9af6d09
aios/validator PR35 Phase A PASS evidence_sha256=b4d4f5a559e411bd5173d6d076cb484e3983ef29db14b778ffd49d889ddebcda
governance/authority-mirror PR35 Phase A PASS evidence_sha256=568f582e530d1cea4af3a117ed98e041462ca9011d4bfe2fafe7a67fd4688103
governance/fault-injection PR35 Phase A PASS evidence_sha256=e1a2551809ae5800eb701c0ae9a5862f3dae166a43ffc8acab68aa218728a6b4
governance/runtime-isolation PR35 Phase A PASS evidence_sha256=e5be2a28129c65d020f7221fc2076550d029187b0cc02c7100fb02574787cb12
governance/schema-contract PR35 Phase A PASS evidence_sha256=2b7e282c41a7e8bd02a85181d8483623449021bed3c8d9890aedaf2f550ab0d4
governance/validator-security PR35 Phase A PASS evidence_sha256=1abe11b6fe05a5318f8cf133749d62bd28292d6252f0c61726f7b2efd918c887
2026-07-31 16:17:30 +08:00
codex ebd7439874 Merge pull request '[SINGLE OWNER LIVE ACTIVATION HARDENING] Implementation and Execution' (#33) from governance/request/single-owner-live-activation-hardening-20260729T043149Z into governance/approvals
Reviewed-on: #33
Reviewed-by: gpt <gpt@imruyi.top>
Reviewed-by: codex <codex@imruyi.top>
2026-07-29 12:45:22 +08:00
Codex Agent c41e278c59 governance: approve live activation hardening
aios/branch-protection AIOS governed hardening gate PASS
aios/evidence-closure AIOS governed hardening gate PASS
aios/secret-scan AIOS governed hardening gate PASS
aios/state-machine AIOS governed hardening gate PASS
aios/validator AIOS governed hardening gate PASS
2026-07-29 12:31:49 +08:00
gpt 1071979079 Merge pull request '[SINGLE OWNER LIVE ACTIVATION] Implementation and Execution' (#32) from governance/request/single-owner-governance-live-activation-20260729T033228Z into governance/approvals
Reviewed-on: #32
Reviewed-by: codex <codex@imruyi.top>
Reviewed-by: gpt <gpt@imruyi.top>
2026-07-29 11:42:55 +08:00
Codex Agent 9a158fcab9 governance: request single-owner live activation 2026-07-29 11:32:28 +08:00
gpt 8b7f9d9028 Merge pull request '[OWNER RATIFICATION] PR #30 Single-Owner Atomic Activation' (#31) from governance/request/single-owner-atomic-activation-owner-ratification-20260729T014918Z-e503d96665ee into governance/approvals
Reviewed-on: #31
Reviewed-by: codex <codex@imruyi.top>
Reviewed-by: gpt <gpt@imruyi.top>
2026-07-29 09:57:54 +08:00
AIOS Governance Requester 3aa1872084 governance: request PR30 owner ratification 2026-07-29 09:49:19 +08:00
gpt f6bef90633 Merge pull request '[SINGLE OWNER GOVERNANCE ATOMIC ACTIVATION] Activate Machine-Gated Owner Policy' (#30) from governance/request/single-owner-governance-atomic-activation-20260728T204808Z-4cab1d5829d6 into governance/approvals
Reviewed-on: #30
Reviewed-by: codex <codex@imruyi.top>
Reviewed-by: gpt <gpt@imruyi.top>
2026-07-29 09:25:08 +08:00
AIOS Governance Requester c2eed5b379 governance: request atomic single-owner activation 2026-07-29 04:48:09 +08:00
codex 6e8212608e Merge pull request '[SINGLE OWNER ACTIVATION PREREQUISITES] Safe Atomic Control Plane' (#29) from governance/request/single-owner-governance-activation-prerequisites-20260728T183025127107Z into governance/approvals
Reviewed-on: #29
Reviewed-by: gpt <gpt@imruyi.top>
Reviewed-by: codex <codex@imruyi.top>
2026-07-29 02:49:26 +08:00
AIOS Activation Prerequisites Requester e6a53888fe governance: request activation prerequisites 2026-07-29 02:30:25 +08:00
gpt 2bef44f6bc Merge pull request '[FINAL OWNER RATIFICATION] Single Owner Governance Activation' (#28) from governance/request/single-owner-governance-final-owner-ratification-20260728T173634412838Z into governance/approvals
Reviewed-on: #28
Reviewed-by: codex <codex@imruyi.top>
Reviewed-by: gpt <gpt@imruyi.top>
2026-07-29 01:46:57 +08:00
AIOS Final Owner Ratification Requester a96f36bf72 governance: request final owner ratification 2026-07-29 01:36:35 +08:00
gpt 4e6ef70029 Merge pull request '[OWNER RATIFICATION + CONTROL PLANE] Single Owner Governance Activation' (#27) from governance/request/single-owner-control-plane-deployment-20260728T170740Z-ea7a102dac417c23 into governance/approvals
Reviewed-on: #27
Reviewed-by: codex <codex@imruyi.top>
Reviewed-by: gpt <gpt@imruyi.top>
2026-07-29 01:11:56 +08:00
AIOS Governance Recovery Requester 80feef309f governance: request owner ratification and control-plane deployment 2026-07-29 01:07:41 +08:00
gpt a5489f1b67 Merge pull request '[OWNER BREAK-GLASS GOVERNANCE RESET] Single Owner with Machine Gates' (#26) from governance/request/single-owner-governance-migration-20260728T162246Z into governance/approvals
Reviewed-on: #26
Reviewed-by: codex <codex@imruyi.top>
Reviewed-by: gpt <gpt@imruyi.top>
2026-07-29 00:39:54 +08:00
AIOS Governance Migration Requester 312d3b4830 governance: propose single-owner machine-gated model 2026-07-29 00:22:47 +08:00
gpt ac2dc5c30e Merge pull request '[CONTROL PLANE DEPLOYMENT] AIOS Integration Refresh Provisioner' (#25) from governance/request/integration-refresh-control-plane-deployment-20260728T093428Z into governance/approvals
Reviewed-on: #25
Reviewed-by: codex <codex@imruyi.top>
Reviewed-by: gpt <gpt@imruyi.top>
2026-07-28 18:35:26 +08:00
AIOS Governance Request Publisher 5ef261b265 governance: request integration refresh control-plane deployment 2026-07-28 17:34:29 +08:00
gpt 3a22c3c7d8 Merge pull request '[SOURCE MAPPING EXECUTION RENEWAL] AIOS Integration Refresh Runtime Sources' (#24) from governance/request/integration-refresh-source-mapping-execution-renewal-20260728T061044Z into governance/approvals
Reviewed-on: #24
Reviewed-by: gpt <gpt@imruyi.top>
Reviewed-by: codex <codex@imruyi.top>
2026-07-28 16:12:41 +08:00
chatgpt-gitops-bot 1c9f28a613 governance: renew source mapping execution window 2026-07-28 14:10:44 +08:00
gpt 9514062cf3 Merge pull request '[SOURCE CANONICALIZATION] AIOS Integration Refresh Runtime Sources' (#23) from governance/request/integration-refresh-source-canonicalization-20260727 into governance/approvals
Reviewed-on: #23
Reviewed-by: codex <codex@imruyi.top>
Reviewed-by: gpt <gpt@imruyi.top>
2026-07-28 02:41:45 +08:00
AIOS Governance Automation a701a32cb4 governance(approval): request source secret remediation 2026-07-27 18:36:27 +08:00
codex 45f3226662 Merge pull request '[IMPLEMENTATION APPROVAL RENEWAL] AIOS Integration Refresh Provisioner' (#22) from governance/request/integration-refresh-provisioner-implementation-renewal-20260727 into governance/approvals
Reviewed-on: #22
Reviewed-by: gpt <gpt@imruyi.top>
Reviewed-by: codex <codex@imruyi.top>
2026-07-27 14:07:37 +08:00
AIOS Governance Automation 975d239d40 governance(approval): renew Integration Refresh Provisioner implementation 2026-07-27 13:00:11 +08:00
codex 3bc44accb5 Merge pull request '[IMPLEMENTATION APPROVAL] AIOS Integration Refresh Provisioner' (#21) from governance/request/integration-refresh-provisioner-implementation-20260726 into governance/approvals
Reviewed-on: #21
2026-07-27 03:58:14 +08:00
gva1785094553523a25 3304d87872 governance(approval): request Integration Refresh Provisioner implementation 2026-07-27 03:35:56 +08:00
gitops-bot 875d41c310 Merge pull request 'fix(gitops): harden Codex worker systemd profile' (#19) from patch/isolated-writer-systemd-profile-hardening-20260725 into main 2026-07-25 11:13:31 +08:00
chatgpt-gitops-bot 870ac61dc2 fix(gitops): harden Codex worker systemd profile 2026-07-25 11:08:55 +08:00
gitops-bot 009f276699 Merge pull request 'fix(gitops): add exact-path service policy for isolated writer' (#18) from patch/isolated-writer-exact-path-policy-20260725 into main 2026-07-25 10:19:02 +08:00
chatgpt-gitops-bot 600c717e17 fix(gitops): add exact-path service policy for isolated writer 2026-07-25 10:16:43 +08:00
gitops-bot 02be6d28ed merge(gitops): add constrained writer token policy and atomic commit-file
Source: patch/isolated-writer-token-policy-v2-20260724
Source commit: b1e240dda3
Target base: df099420d2
Production runtime changes: not authorized
Tag/Baseline/Registry operations: not authorized
2026-07-24 23:36:25 +08:00
chatgpt-gitops-bot b1e240dda3 fix(gitops): reject atomic writer force fields 2026-07-24 23:06:22 +08:00
chatgpt-gitops-bot 2dfbe837f4 fix(gitops): bind writer runtime policy v2 artifacts 2026-07-24 23:01:40 +08:00
chatgpt-gitops-bot 80df1e0d87 test(gitops): close writer authz and recovery contract 2026-07-24 22:56:58 +08:00
chatgpt-gitops-bot 7ecf7cbfce feat(gitops): add idempotent atomic commit-file endpoint 2026-07-24 22:56:58 +08:00
chatgpt-gitops-bot bbada7c863 feat(gitops): add constrained writer token policy v2 2026-07-24 22:56:58 +08:00
57 changed files with 7464 additions and 1894 deletions
@@ -5,13 +5,148 @@ import json
import os
import subprocess
from pathlib import Path
import urllib.parse
import aios_chatgpt_actions_api as api
import aios_isolated_writer_policy as policy
from isolated_writer_authz import AuthorizationError, authorize
from isolated_writer_commit_file import AtomicCommitFile, CommitFileError, OperationLedger
from isolated_writer_token_registry import TokenRegistry
_reject = api.reject_non_read_http
_write_file = api.write_file
_sync_branch = api.sync_branch
_original_do_get = api.H.do_GET
api.OPENAPI = Path(os.getenv("AIOS_GITOPS_ISOLATED_WRITER_OPENAPI", str(api.OPENAPI)))
def _registry() -> TokenRegistry:
return TokenRegistry(Path(os.environ["AIOS_GITOPS_TOKEN_REGISTRY_V2"]))
def _atomic_writer() -> AtomicCommitFile:
return AtomicCommitFile(
workspace=api.WS,
bare_repo=api.BARE_REPO,
ledger=OperationLedger(Path(os.environ["AIOS_GITOPS_WRITER_OPERATION_LEDGER"])),
remote=os.getenv("AIOS_GITOPS_GITEA_PUSH_REMOTE", ""),
audit=policy.append_audit_record,
)
def _bearer(handler) -> str:
value = handler.headers.get("Authorization", "")
return value[7:].strip() if value.startswith("Bearer ") else ""
def _authorize(handler, *, method: str, path: str, branch=None, target_path=None):
grant = authorize(
_registry(),
_bearer(handler),
method=method,
path=path,
source_ip=str(handler.client_address[0]),
workspace=api.WS,
branch=branch,
target_path=target_path,
)
grant.record["_source_ip"] = str(handler.client_address[0])
return grant
def _authorization_error(handler, exc: AuthorizationError):
return handler.sendj({"error": exc.code}, exc.status)
def _isolated_runtime_status(handler):
branch = api.sh(["rev-parse", "--abbrev-ref", "HEAD"], True)["stdout"]
head = api.sh(["rev-parse", "HEAD"], True)["stdout"]
return handler.sendj({
"service": os.getenv(
"AIOS_GITOPS_SERVICE_AUDIENCE",
"aios-isolated-writer.service",
),
"status": "active",
"runtime_role": os.getenv("AIOS_GITOPS_RUNTIME_ROLE"),
"workspace_role": os.getenv("AIOS_GITOPS_WORKSPACE_ROLE"),
"writes_enabled": os.getenv("AIOS_GITOPS_WRITES_ENABLED", "").lower()
in {"1", "true", "yes", "on"},
"allowed_branch": policy.allowed_branch(),
"approved_base_oid": policy.allowed_base_oid(),
"workspace_branch": branch,
"workspace_head_oid": head,
"repository_identity": os.getenv("AIOS_GITOPS_REPOSITORY_IDENTITY"),
"token_policy_version": 2,
"atomic_commit_file": True,
"path_policy_sha256": policy.configured_path_policy_sha256(),
})
def _isolated_do_get(self):
path = urllib.parse.urlparse(self.path).path.rstrip("/") or "/"
if path in {"/health", "/api/health"}:
return self.sendj({
"status": "ok",
"service": os.getenv(
"AIOS_GITOPS_SERVICE_AUDIENCE",
"aios-isolated-writer.service",
),
})
if path not in {"/api/runtime-status", "/api/baseline", "/api/patches"}:
return self.sendj({"error": "isolated_writer_operation_forbidden"}, 403)
try:
_authorize(self, method="GET", path=path)
except AuthorizationError as exc:
return _authorization_error(self, exc)
if path == "/api/runtime-status":
return _isolated_runtime_status(self)
return _original_do_get(self)
def _read_commit_file_body(handler):
try:
length = int(handler.headers.get("Content-Length", "0"))
except ValueError:
raise CommitFileError("writer_content_length_rejected") from None
if length <= 0:
raise CommitFileError("writer_request_object_required")
if length > 1_100_000:
raise CommitFileError("writer_request_too_large", 413)
raw = handler.rfile.read(length)
try:
value = json.loads(raw.decode("utf-8"))
except (UnicodeDecodeError, json.JSONDecodeError):
raise CommitFileError("writer_request_json_rejected") from None
if not isinstance(value, dict):
raise CommitFileError("writer_request_object_required")
return value
def _isolated_do_post(self):
path = urllib.parse.urlparse(self.path).path.rstrip("/") or "/"
if path != "/api/commit-file":
return self.sendj({"error": "isolated_writer_operation_forbidden"}, 403)
try:
data = _read_commit_file_body(self)
branch = str(data.get("branch") or "")
target_path = str(data.get("path") or "")
grant = _authorize(
self,
method="POST",
path=path,
branch=branch,
target_path=target_path,
)
if api.content_has_secret(str(data.get("content") or "")):
raise CommitFileError("writer_secret_content_rejected", 403)
result = _atomic_writer().execute(grant, data)
return self.sendj(result)
except AuthorizationError as exc:
return _authorization_error(self, exc)
except CommitFileError as exc:
return self.sendj({"error": exc.code}, exc.status)
except PermissionError:
return self.sendj({"error": "isolated_writer_policy_rejected"}, 403)
def reject_non_read_http(handler, method: str, path: str) -> bool:
@@ -173,6 +308,8 @@ api.H.branch, api.H.file, api.H.commit, api.H.patch = (
_checked_commit,
_checked_patch,
)
api.H.do_GET = _isolated_do_get
api.H.do_POST = _isolated_do_post
if __name__ == "__main__":
policy.require_service_invariants(api.WS, api.BARE_REPO)
@@ -9,10 +9,9 @@ import re
from pathlib import Path, PurePosixPath, PureWindowsPath
from urllib.parse import unquote
WRITE_ENDPOINTS = frozenset({
"/api/branch", "/api/create-branch", "/api/file", "/api/commit-file",
"/api/commit", "/api/patch", "/api/create-patch",
})
import isolated_writer_path_policy as path_policy
WRITE_ENDPOINTS = frozenset({"/api/commit-file"})
ALLOWED_ROOTS = (
"active-runtime",
"docs",
@@ -69,6 +68,15 @@ def require_service_invariants(workspace: Path, bare_repo: Path) -> None:
raise PermissionError("isolated_writer_role_required")
if os.getenv("AIOS_GITOPS_WORKSPACE_ROLE", "") != "isolated-writer":
raise PermissionError("isolated_writer_workspace_role_required")
if os.getenv("AIOS_GITOPS_TOKEN_POLICY_VERSION_REQUIRED", "") != "2":
raise PermissionError("isolated_writer_token_policy_v2_required")
if not os.getenv("AIOS_GITOPS_SERVICE_AUDIENCE", "").strip():
raise PermissionError("isolated_writer_service_audience_required")
if not os.getenv("AIOS_GITOPS_TOKEN_REGISTRY_V2", "").strip():
raise PermissionError("isolated_writer_token_registry_required")
if not os.getenv("AIOS_GITOPS_WRITER_OPERATION_LEDGER", "").strip():
raise PermissionError("isolated_writer_operation_ledger_required")
path_policy.configured_path_policy()
for name in _DENY_FLAGS:
if os.getenv(name, "").strip().lower() not in _FALSE:
raise PermissionError("isolated_writer_forbidden_capability_flag")
@@ -182,6 +190,7 @@ def _audit_sanitize(value):
"private_key",
)
)
and str(key).lower() != "token_id"
else _audit_sanitize(inner)
)
for key, inner in value.items()
@@ -239,9 +248,14 @@ def validate_path(path: str, workspace: Path | None = None) -> str:
):
raise PermissionError("isolated_writer_path_rejected")
first = parts[0]
service_exact_path = False
if first in DENIED_ROOTS:
raise PermissionError("isolated_writer_protected_path_rejected")
if value != "README.md" and first not in ALLOWED_ROOTS:
try:
path_policy.require_service_path("commit_file.atomic", value)
service_exact_path = True
except path_policy.PathPolicyError as exc:
raise PermissionError(str(exc)) from None
if value != "README.md" and first not in ALLOWED_ROOTS and not service_exact_path:
raise PermissionError("isolated_writer_path_outside_allowed_roots")
if workspace is not None:
lexical_root = Path(os.path.abspath(str(workspace)))
@@ -261,6 +275,22 @@ def validate_path(path: str, workspace: Path | None = None) -> str:
return value
def validate_content_for_path(path: str, content: str) -> None:
if path.split("/", 1)[0] not in DENIED_ROOTS:
return
try:
path_policy.validate_content("commit_file.atomic", path, content)
except path_policy.PathPolicyError as exc:
raise PermissionError(str(exc)) from None
def configured_path_policy_sha256() -> str | None:
try:
return path_policy.configured_path_policy_sha256()
except path_policy.PathPolicyError as exc:
raise PermissionError(str(exc)) from None
def validate_commit_paths(paths: list[str], workspace: Path | None = None) -> None:
if enforcement_required():
for path in paths:
+167
View File
@@ -0,0 +1,167 @@
"""Fail-closed operation authorization for an isolated Git writer."""
from __future__ import annotations
import ipaddress
import os
import re
import subprocess
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
from isolated_writer_token_registry import TokenRegistry
ROUTE_OPERATIONS = {
("GET", "/api/runtime-status"): "runtime.status.read",
("GET", "/api/baseline"): "baseline.read",
("GET", "/api/patches"): "patches.read",
("POST", "/api/commit-file"): "commit_file.atomic",
}
OID_RE = re.compile(r"[0-9a-f]{40}")
class AuthorizationError(PermissionError):
def __init__(self, code: str, status: int = 403):
super().__init__(code)
self.code = code
self.status = status
@dataclass(frozen=True)
class AuthorizedGrant:
record: dict[str, Any]
operation: str
use_count: int
@property
def token_id(self) -> str:
return str(self.record["token_id"])
@property
def task_id(self) -> str:
return str(self.record["task_id"])
def operation_for(method: str, path: str) -> str:
operation = ROUTE_OPERATIONS.get((method.upper(), path))
if not operation:
raise AuthorizationError("isolated_writer_operation_forbidden")
return operation
def _parse_time(value: Any) -> datetime:
try:
parsed = datetime.fromisoformat(str(value).replace("Z", "+00:00"))
except (TypeError, ValueError):
raise AuthorizationError("writer_token_time_invalid") from None
if parsed.tzinfo is None:
raise AuthorizationError("writer_token_time_invalid")
return parsed.astimezone(timezone.utc)
def _git_is_ancestor(workspace: Path, base: str, branch: str) -> bool:
result = subprocess.run(
["git", "merge-base", "--is-ancestor", base, branch],
cwd=workspace,
stdout=subprocess.DEVNULL,
stderr=subprocess.DEVNULL,
)
return result.returncode == 0
def _validate_grant(
grant: dict[str, Any],
*,
audience: str,
source_ip: str,
operation: str,
branch: str | None,
path: str | None,
workspace: Path,
current_time: datetime,
) -> None:
if int(grant.get("schema_version", 0)) != 2:
raise AuthorizationError("writer_token_policy_v2_required", 401)
if str(grant.get("audience") or "") != audience:
raise AuthorizationError("writer_token_audience_rejected")
try:
peer = ipaddress.ip_address(source_ip)
networks = [ipaddress.ip_network(str(value), strict=True) for value in grant.get("source_cidrs", [])]
except ValueError:
raise AuthorizationError("writer_token_source_rejected") from None
if not networks or not any(peer in network for network in networks):
raise AuthorizationError("writer_token_source_rejected")
created = _parse_time(grant.get("created_at"))
not_before = _parse_time(grant.get("not_before"))
expires = _parse_time(grant.get("expires_at"))
if expires <= not_before or (expires - created).total_seconds() > 1800:
raise AuthorizationError("writer_token_lifetime_rejected")
if current_time < not_before:
raise AuthorizationError("writer_token_not_yet_valid", 401)
if current_time >= expires:
raise AuthorizationError("writer_token_expired", 401)
if bool(grant.get("revoked")):
raise AuthorizationError("writer_token_revoked", 401)
operations = grant.get("allowed_operations")
if not isinstance(operations, list) or operation not in operations:
raise AuthorizationError("writer_token_operation_rejected")
expected_branch = str(grant.get("allowed_branch") or "")
configured_branch = os.getenv("AIOS_GITOPS_ALLOWED_BRANCH", "")
if expected_branch != configured_branch:
raise AuthorizationError("writer_token_branch_rejected")
if branch is not None and branch != expected_branch:
raise AuthorizationError("writer_token_branch_rejected")
if path is not None:
paths = grant.get("allowed_paths")
if not isinstance(paths, list) or path not in paths:
raise AuthorizationError("writer_token_path_rejected")
base = str(grant.get("approved_base_oid") or "").lower()
if not OID_RE.fullmatch(base):
raise AuthorizationError("writer_token_base_rejected")
if not _git_is_ancestor(workspace, base, expected_branch):
raise AuthorizationError("writer_token_base_not_ancestor")
def authorize(
registry: TokenRegistry,
token: str,
*,
method: str,
path: str,
source_ip: str,
workspace: Path,
branch: str | None = None,
target_path: str | None = None,
current_time: datetime | None = None,
) -> AuthorizedGrant:
if os.getenv("AIOS_GITOPS_TOKEN_POLICY_VERSION_REQUIRED", "") != "2":
raise AuthorizationError("writer_token_policy_v2_not_required")
if not token:
raise AuthorizationError("unauthorized", 401)
grant = registry.find(token)
if grant is None:
raise AuthorizationError("unauthorized", 401)
operation = operation_for(method, path)
_validate_grant(
grant,
audience=os.getenv("AIOS_GITOPS_SERVICE_AUDIENCE", ""),
source_ip=source_ip,
operation=operation,
branch=branch,
path=target_path,
workspace=workspace,
current_time=current_time or datetime.now(timezone.utc),
)
limits = grant.get("max_uses")
if not isinstance(limits, dict):
raise AuthorizationError("writer_token_use_limit_missing")
try:
used = registry.consume(str(grant["token_id"]), operation, int(limits[operation]))
except (KeyError, TypeError, ValueError):
raise AuthorizationError("writer_token_use_limit_missing") from None
except PermissionError as exc:
code = str(exc)
raise AuthorizationError(code, 401 if code == "writer_token_revoked" else 403) from None
return AuthorizedGrant(grant, operation, used)
@@ -0,0 +1,403 @@
"""Atomic, idempotent commit-file Saga for the isolated writer."""
from __future__ import annotations
import fcntl
import hashlib
import json
import os
import re
import sqlite3
import subprocess
import tempfile
import threading
from pathlib import Path
from typing import Any
import aios_isolated_writer_policy as policy
OID_RE = re.compile(r"[0-9a-f]{40}")
IDEMPOTENCY_RE = re.compile(r"[A-Za-z0-9][A-Za-z0-9._:-]{7,127}")
STATES = frozenset({
"PENDING", "FILE_WRITTEN", "COMMITTED", "PUSHED", "VERIFIED", "COMPLETED",
"FAILED_RECOVERABLE", "MANUAL_REVIEW_REQUIRED",
})
_LOCKS: dict[str, threading.Lock] = {}
_LOCKS_GUARD = threading.Lock()
_LEDGER_INIT_LOCK = threading.Lock()
class CommitFileError(RuntimeError):
def __init__(self, code: str, status: int = 400):
super().__init__(code)
self.code = code
self.status = status
class SimulatedCrash(RuntimeError):
pass
def canonical_digest(data: dict[str, Any]) -> str:
payload = {
"branch": data["branch"],
"path": data["path"],
"content_sha256": hashlib.sha256(data["content"].encode("utf-8")).hexdigest(),
"message": data["message"],
"expected_head_oid": data["expected_head_oid"],
}
encoded = json.dumps(payload, sort_keys=True, separators=(",", ":")).encode("utf-8")
return hashlib.sha256(encoded).hexdigest()
class OperationLedger:
def __init__(self, path: Path | str):
self.path = Path(path)
self.path.parent.mkdir(parents=True, exist_ok=True)
if self.path.parent.is_symlink() or self.path.is_symlink():
raise PermissionError("writer_operation_ledger_symlink_rejected")
with _LEDGER_INIT_LOCK:
with self.connect() as db:
db.execute(
"""
CREATE TABLE IF NOT EXISTS writer_operations (
operation_id TEXT PRIMARY KEY,
token_id TEXT NOT NULL,
task_id TEXT NOT NULL,
idempotency_key TEXT NOT NULL UNIQUE,
operation_digest TEXT NOT NULL,
branch TEXT NOT NULL,
path TEXT NOT NULL,
content_sha256 TEXT NOT NULL,
pre_head_oid TEXT NOT NULL,
commit_oid TEXT,
push_status TEXT,
verification_status TEXT,
state TEXT NOT NULL,
created_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
updated_at TEXT NOT NULL DEFAULT CURRENT_TIMESTAMP,
error_code TEXT
)
"""
)
os.chmod(self.path, 0o600)
def connect(self) -> sqlite3.Connection:
db = sqlite3.connect(self.path, timeout=30)
db.row_factory = sqlite3.Row
db.execute("PRAGMA journal_mode=WAL")
db.execute("PRAGMA synchronous=FULL")
return db
def get_or_create(self, grant: Any, data: dict[str, Any], digest: str) -> dict[str, Any]:
key = data["idempotency_key"]
with self.connect() as db:
db.execute("BEGIN IMMEDIATE")
row = db.execute(
"SELECT * FROM writer_operations WHERE idempotency_key=?", (key,)
).fetchone()
if row:
db.commit()
record = dict(row)
if record["operation_digest"] != digest:
raise CommitFileError("writer_idempotency_conflict", 409)
if (
record["token_id"] != grant.token_id
or record["task_id"] != grant.task_id
):
raise CommitFileError("writer_idempotency_owner_conflict", 409)
return record
operation_id = hashlib.sha256(
f"{grant.task_id}\0{key}".encode("utf-8")
).hexdigest()
content_sha = hashlib.sha256(data["content"].encode("utf-8")).hexdigest()
db.execute(
"""
INSERT INTO writer_operations(
operation_id,token_id,task_id,idempotency_key,operation_digest,
branch,path,content_sha256,pre_head_oid,state
) VALUES(?,?,?,?,?,?,?,?,?,?)
""",
(
operation_id, grant.token_id, grant.task_id, key, digest,
data["branch"], data["path"], content_sha,
data["expected_head_oid"], "PENDING",
),
)
db.commit()
return self.get(key)
def get(self, key: str) -> dict[str, Any]:
with self.connect() as db:
row = db.execute(
"SELECT * FROM writer_operations WHERE idempotency_key=?", (key,)
).fetchone()
if row is None:
raise KeyError(key)
return dict(row)
def update(self, key: str, state: str, **fields: Any) -> dict[str, Any]:
if state not in STATES:
raise ValueError("invalid writer operation state")
allowed = {"commit_oid", "push_status", "verification_status", "error_code"}
assignments = ["state=?", "updated_at=CURRENT_TIMESTAMP"]
values: list[Any] = [state]
for name, value in fields.items():
if name not in allowed:
raise ValueError("invalid ledger field")
assignments.append(f"{name}=?")
values.append(value)
values.append(key)
with self.connect() as db:
db.execute("BEGIN IMMEDIATE")
db.execute(
f"UPDATE writer_operations SET {','.join(assignments)} WHERE idempotency_key=?",
values,
)
db.commit()
return self.get(key)
class AtomicCommitFile:
def __init__(
self,
*,
workspace: Path,
bare_repo: Path,
ledger: OperationLedger,
remote: str,
audit,
crash_after_state: str | None = None,
):
self.workspace = workspace
self.bare_repo = bare_repo
self.ledger = ledger
self.remote = remote
self.audit = audit
self.crash_after_state = crash_after_state
def _git(self, *args: str, check: bool = True) -> str:
result = subprocess.run(
["git", *args], cwd=self.workspace, text=True, capture_output=True
)
if check and result.returncode != 0:
raise CommitFileError("writer_git_operation_failed", 500)
return result.stdout.strip()
def _transition(self, key: str, state: str, **fields: Any) -> dict[str, Any]:
record = self.ledger.update(key, state, **fields)
if self.crash_after_state == state:
raise SimulatedCrash(state)
return record
def _validate(self, data: Any) -> dict[str, Any]:
if not isinstance(data, dict):
raise CommitFileError("writer_request_object_required")
required = ("branch", "path", "content", "message", "expected_head_oid", "idempotency_key")
if any(field not in data for field in required):
raise CommitFileError("writer_request_incomplete")
if data.get("force") or data.get("force_push"):
raise CommitFileError("isolated_writer_force_rejected", 403)
if set(data) != set(required):
raise CommitFileError("writer_request_fields_rejected")
item = {field: data[field] for field in required}
if item["branch"] != policy.allowed_branch():
raise CommitFileError("isolated_writer_branch_rejected", 403)
try:
item["path"] = policy.validate_path(item["path"], self.workspace)
except PermissionError as exc:
raise CommitFileError(str(exc), 403) from None
if not isinstance(item["content"], str) or "\x00" in item["content"]:
raise CommitFileError("writer_content_rejected")
try:
policy.validate_content_for_path(item["path"], item["content"])
except PermissionError as exc:
raise CommitFileError(str(exc), 403) from None
if len(item["content"].encode("utf-8")) > 1_048_576:
raise CommitFileError("writer_content_too_large", 413)
message = item["message"]
if (
not isinstance(message, str)
or not 1 <= len(message) <= 200
or "\x00" in message
or "\n" in message
or "\r" in message
):
raise CommitFileError("writer_message_rejected")
if not isinstance(item["expected_head_oid"], str) or not OID_RE.fullmatch(item["expected_head_oid"]):
raise CommitFileError("writer_expected_head_rejected")
if not isinstance(item["idempotency_key"], str) or not IDEMPOTENCY_RE.fullmatch(item["idempotency_key"]):
raise CommitFileError("writer_idempotency_key_rejected")
return item
def _atomic_write(self, relative: str, content: str) -> None:
target = self.workspace / relative
target.parent.mkdir(parents=True, exist_ok=True)
fd, temporary = tempfile.mkstemp(prefix=".writer-", dir=target.parent)
try:
with os.fdopen(fd, "wb", closefd=True) as stream:
stream.write(content.encode("utf-8"))
stream.flush()
os.fsync(stream.fileno())
os.replace(temporary, target)
parent_fd = os.open(target.parent, os.O_RDONLY | getattr(os, "O_DIRECTORY", 0))
try:
os.fsync(parent_fd)
finally:
os.close(parent_fd)
finally:
if os.path.exists(temporary):
os.unlink(temporary)
def _verify_remote(self, branch: str, oid: str) -> None:
bare = subprocess.run(
["git", "--git-dir", str(self.bare_repo), "rev-parse", f"refs/heads/{branch}"],
text=True, capture_output=True,
)
if bare.returncode != 0 or bare.stdout.strip() != oid:
raise CommitFileError("writer_authoritative_bare_oid_mismatch", 500)
remote = subprocess.run(
["git", "ls-remote", "--heads", self.remote, f"refs/heads/{branch}"],
cwd=self.workspace, text=True, capture_output=True,
)
if remote.returncode != 0:
raise CommitFileError("writer_gitea_verification_failed", 503)
fields = remote.stdout.strip().split()
if len(fields) != 2:
raise CommitFileError("writer_gitea_ref_missing", 503)
if fields[0] != oid:
raise CommitFileError("writer_gitea_oid_conflict", 409)
def execute(self, grant: Any, raw_data: Any) -> dict[str, Any]:
data = self._validate(raw_data)
digest = canonical_digest(data)
branch = data["branch"]
with _LOCKS_GUARD:
lock = _LOCKS.setdefault(branch, threading.Lock())
lock_path = self.ledger.path.parent / f"{hashlib.sha256(branch.encode()).hexdigest()}.lock"
with lock, open(lock_path, "a+b") as branch_lock:
fcntl.flock(branch_lock.fileno(), fcntl.LOCK_EX)
return self._execute_locked(grant, data, digest)
def _execute_locked(self, grant: Any, data: dict[str, Any], digest: str) -> dict[str, Any]:
key = data["idempotency_key"]
record = self.ledger.get_or_create(grant, data, digest)
if record["state"] == "COMPLETED":
return self._result(record, idempotent=True)
if self._git("rev-parse", "--abbrev-ref", "HEAD") != data["branch"]:
record = self._transition(
key, "MANUAL_REVIEW_REQUIRED", error_code="writer_current_branch_conflict"
)
self._audit(grant, data, digest, record, "manual_review_required")
raise CommitFileError("writer_current_branch_conflict", 409)
head = self._git("rev-parse", "HEAD")
commit_oid = record.get("commit_oid")
if head != record["pre_head_oid"] and head != commit_oid:
record = self._transition(
key, "MANUAL_REVIEW_REQUIRED", error_code="writer_branch_head_conflict"
)
self._audit(grant, data, digest, record, "manual_review_required")
raise CommitFileError("writer_branch_head_conflict", 409)
try:
state = record["state"]
if state == "MANUAL_REVIEW_REQUIRED":
raise CommitFileError("writer_manual_review_required", 409)
if state == "FAILED_RECOVERABLE":
if record.get("push_status") == "confirmed":
state = "PUSHED"
else:
state = "COMMITTED" if commit_oid else "FILE_WRITTEN"
if state == "PENDING":
self._atomic_write(data["path"], data["content"])
record = self._transition(key, "FILE_WRITTEN")
state = record["state"]
if state == "FILE_WRITTEN":
actual_sha = hashlib.sha256(
(self.workspace / data["path"]).read_bytes()
).hexdigest()
if actual_sha != record["content_sha256"]:
raise CommitFileError("writer_file_content_conflict", 409)
staged_before = self._git("diff", "--cached", "--name-only", check=False).splitlines()
if staged_before:
raise CommitFileError("writer_extra_staged_files_rejected", 409)
self._git("add", "--", data["path"])
staged = self._git("diff", "--cached", "--name-only").splitlines()
if staged != [data["path"]]:
raise CommitFileError("writer_extra_staged_files_rejected", 409)
self._git("commit", "-m", data["message"])
commit_oid = self._git("rev-parse", "HEAD")
record = self._transition(key, "COMMITTED", commit_oid=commit_oid)
state = record["state"]
if state == "COMMITTED":
commit_oid = str(record["commit_oid"])
pushed = subprocess.run(
["git", "push", "--porcelain", self.remote, f"HEAD:refs/heads/{data['branch']}"],
cwd=self.workspace, text=True, capture_output=True,
)
if pushed.returncode != 0:
self._transition(
key, "FAILED_RECOVERABLE",
push_status="failed", error_code="writer_gitea_push_failed",
)
raise CommitFileError("writer_gitea_push_failed", 503)
record = self._transition(key, "PUSHED", push_status="confirmed")
state = record["state"]
if state == "PUSHED":
commit_oid = str(record["commit_oid"])
self._verify_remote(data["branch"], commit_oid)
record = self._transition(
key, "VERIFIED", verification_status="bare+gitea"
)
state = record["state"]
if state == "VERIFIED":
record = self._transition(key, "COMPLETED", error_code=None)
self._audit(grant, data, digest, record, "completed")
return self._result(record, idempotent=False)
except SimulatedCrash:
raise
except CommitFileError as exc:
latest = self.ledger.get(key)
if latest["state"] not in {"FAILED_RECOVERABLE", "MANUAL_REVIEW_REQUIRED"}:
failure_state = (
"MANUAL_REVIEW_REQUIRED"
if exc.code in {
"writer_gitea_oid_conflict",
"writer_file_content_conflict",
"writer_current_branch_conflict",
}
else "FAILED_RECOVERABLE"
)
latest = self._transition(key, failure_state, error_code=exc.code)
self._audit(grant, data, digest, latest, "failed")
raise
def _audit(self, grant: Any, data: dict[str, Any], digest: str, record: dict[str, Any], result: str) -> None:
self.audit({
"token_id": grant.token_id,
"task_id": grant.task_id,
"audience": grant.record["audience"],
"source_ip": grant.record.get("_source_ip", "socket-peer"),
"operation": grant.operation,
"branch": data["branch"],
"path": data["path"],
"idempotency_key": data["idempotency_key"],
"operation_digest": digest,
"path_policy_sha256": policy.configured_path_policy_sha256(),
"pre_head_oid": record["pre_head_oid"],
"commit_oid": record.get("commit_oid"),
"result": result,
})
@staticmethod
def _result(record: dict[str, Any], *, idempotent: bool) -> dict[str, Any]:
return {
"status": "completed",
"state": record["state"],
"operation_id": record["operation_id"],
"branch": record["branch"],
"path": record["path"],
"commit_oid": record.get("commit_oid"),
"push_status": record.get("push_status"),
"verification_status": record.get("verification_status"),
"idempotent": idempotent,
}
@@ -0,0 +1,422 @@
"""Strict service-level exact-path policy for isolated Git writers."""
from __future__ import annotations
import grp
import hashlib
import json
import os
import re
import stat
from dataclasses import dataclass
from functools import lru_cache
from pathlib import Path, PurePosixPath, PureWindowsPath
from typing import Any
from urllib.parse import unquote
MAX_POLICY_BYTES = 65_536
POLICY_FIELDS = frozenset(
{
"schema_version",
"policy_id",
"audience",
"repository_identity",
"allowed_branch",
"allowed_operations",
}
)
OPERATION_FIELDS = frozenset({"exact_paths", "max_content_bytes", "content_profile"})
SUPPORTED_OPERATIONS = frozenset({"commit_file.atomic"})
SUPPORTED_CONTENT_PROFILES = frozenset({"systemd-codex-review-worker-v1"})
_SECRET_RE = re.compile(
r"(?i)(authorization\s*:|bearer\s+|(?:token|password|secret)\s*[:=])"
)
_SYSTEMD_NAME_RE = re.compile(r"[A-Za-z][A-Za-z0-9]*\Z")
_SYSTEMD_MAX_LINE_BYTES = 4096
_SYSTEMD_ALLOWED_DIRECTIVES = {
"Unit": frozenset({"Description", "After", "Wants"}),
"Service": frozenset(
{
"Type",
"User",
"Group",
"WorkingDirectory",
"Environment",
"ExecStart",
"Restart",
"RestartSec",
"NoNewPrivileges",
"PrivateTmp",
"PrivateDevices",
"ProtectSystem",
"ProtectHome",
"ProtectKernelTunables",
"ProtectKernelModules",
"ProtectControlGroups",
"LockPersonality",
"RestrictSUIDSGID",
"RestrictRealtime",
"MemoryDenyWriteExecute",
"RuntimeDirectory",
"StateDirectory",
"CacheDirectory",
"ReadOnlyPaths",
"ReadWritePaths",
"UMask",
}
),
"Install": frozenset({"WantedBy"}),
}
_SYSTEMD_MULTI_DIRECTIVES = frozenset(
{
("Service", "Environment"),
("Service", "ReadOnlyPaths"),
("Service", "ReadWritePaths"),
}
)
_SYSTEMD_EXACT_SINGLE_VALUES = {
("Unit", "Description"): "AIOS Codex Review/Test Worker",
("Unit", "After"): "network-online.target",
("Unit", "Wants"): "network-online.target",
("Service", "Type"): "simple",
("Service", "User"): "aiman",
("Service", "Group"): "gitops",
(
"Service",
"WorkingDirectory",
): "/usr/libexec/aios-codex-review-test-worker/current",
(
"Service",
"ExecStart",
): "/usr/bin/python3 -m task_plane.workers.codex_review_test",
("Service", "Restart"): "on-failure",
("Service", "RestartSec"): "2",
("Service", "NoNewPrivileges"): "true",
("Service", "PrivateTmp"): "true",
("Service", "PrivateDevices"): "true",
("Service", "ProtectSystem"): "strict",
("Service", "ProtectHome"): "true",
("Service", "ProtectKernelTunables"): "true",
("Service", "ProtectKernelModules"): "true",
("Service", "ProtectControlGroups"): "true",
("Service", "LockPersonality"): "true",
("Service", "RestrictSUIDSGID"): "true",
("Service", "RestrictRealtime"): "true",
("Service", "MemoryDenyWriteExecute"): "true",
("Service", "RuntimeDirectory"): "aios-codex-review-test-worker",
("Service", "StateDirectory"): "aios-codex-review-test-worker",
("Service", "CacheDirectory"): "aios-codex-review-test-worker",
("Service", "UMask"): "0077",
("Install", "WantedBy"): "multi-user.target",
}
_SYSTEMD_EXACT_MULTI_VALUES = {
("Service", "Environment"): (
"AIOS_CODEX_WORKER_MODE=shadow",
"AIOS_TASK_PLANE_EXECUTION_ENABLED=false",
"PYTHONDONTWRITEBYTECODE=1",
),
("Service", "ReadOnlyPaths"): (
"/data/aios-gitops/repo.git",
"/usr/libexec/aios-codex-review-test-worker",
),
("Service", "ReadWritePaths"): (
"/run/aios-codex-review-test-worker",
"/var/lib/aios-codex-review-test-worker",
"/var/cache/aios-codex-review-test-worker",
),
}
class PathPolicyError(PermissionError):
pass
@dataclass(frozen=True)
class OperationPolicy:
exact_paths: tuple[str, ...]
max_content_bytes: int
content_profile: str
@dataclass(frozen=True)
class ServicePathPolicy:
schema_version: int
policy_id: str
audience: str
repository_identity: str
allowed_branch: str
allowed_operations: dict[str, OperationPolicy]
sha256: str
def operation(self, name: str) -> OperationPolicy:
try:
return self.allowed_operations[name]
except KeyError:
raise PathPolicyError("isolated_writer_service_operation_rejected") from None
def require_exact_path(self, operation: str, path: str) -> OperationPolicy:
selected = self.operation(operation)
if path not in selected.exact_paths:
raise PathPolicyError("isolated_writer_service_path_rejected")
return selected
def _canonical_json(value: Any) -> bytes:
return (
json.dumps(value, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
+ "\n"
).encode("utf-8")
def validate_relative_path_syntax(path: str) -> str:
if not isinstance(path, str):
raise PathPolicyError("isolated_writer_path_rejected")
if not path or path != path.strip() or "\x00" in path or "\\" in path:
raise PathPolicyError("isolated_writer_path_rejected")
try:
decoded = unquote(path, errors="strict")
except (UnicodeDecodeError, ValueError):
raise PathPolicyError("isolated_writer_path_rejected") from None
if decoded != path:
raise PathPolicyError("isolated_writer_path_rejected")
posix = PurePosixPath(path)
windows = PureWindowsPath(path)
parts = path.split("/")
if (
posix.is_absolute()
or windows.is_absolute()
or bool(windows.drive)
or any(part in {"", ".", ".."} for part in parts)
):
raise PathPolicyError("isolated_writer_path_rejected")
return path
def _require_fields(value: dict[str, Any], allowed: frozenset[str], code: str) -> None:
if set(value) != allowed:
raise PathPolicyError(code)
def _parse_policy(document: Any, canonical: bytes) -> ServicePathPolicy:
if not isinstance(document, dict):
raise PathPolicyError("isolated_writer_path_policy_object_required")
_require_fields(document, POLICY_FIELDS, "isolated_writer_path_policy_fields_rejected")
if document["schema_version"] != 1:
raise PathPolicyError("isolated_writer_path_policy_schema_rejected")
text_fields = (
"policy_id",
"audience",
"repository_identity",
"allowed_branch",
)
if any(
not isinstance(document[field], str) or not document[field].strip()
for field in text_fields
):
raise PathPolicyError("isolated_writer_path_policy_value_rejected")
raw_operations = document["allowed_operations"]
if not isinstance(raw_operations, dict) or not raw_operations:
raise PathPolicyError("isolated_writer_path_policy_operations_rejected")
if not set(raw_operations).issubset(SUPPORTED_OPERATIONS):
raise PathPolicyError("isolated_writer_path_policy_operations_rejected")
operations: dict[str, OperationPolicy] = {}
for name, raw in raw_operations.items():
if not isinstance(raw, dict):
raise PathPolicyError("isolated_writer_path_policy_operation_rejected")
_require_fields(
raw,
OPERATION_FIELDS,
"isolated_writer_path_policy_operation_fields_rejected",
)
paths = raw["exact_paths"]
if (
not isinstance(paths, list)
or not paths
or any(not isinstance(item, str) for item in paths)
):
raise PathPolicyError("isolated_writer_path_policy_paths_rejected")
validated = tuple(validate_relative_path_syntax(item) for item in paths)
if len(set(validated)) != len(validated):
raise PathPolicyError("isolated_writer_path_policy_paths_rejected")
maximum = raw["max_content_bytes"]
if not isinstance(maximum, int) or isinstance(maximum, bool) or not 1 <= maximum <= 1_048_576:
raise PathPolicyError("isolated_writer_path_policy_size_rejected")
profile = raw["content_profile"]
if profile not in SUPPORTED_CONTENT_PROFILES:
raise PathPolicyError("isolated_writer_path_policy_profile_rejected")
operations[name] = OperationPolicy(validated, maximum, profile)
return ServicePathPolicy(
schema_version=1,
policy_id=document["policy_id"],
audience=document["audience"],
repository_identity=document["repository_identity"],
allowed_branch=document["allowed_branch"],
allowed_operations=operations,
sha256=hashlib.sha256(canonical).hexdigest(),
)
def load_path_policy(
path: Path,
*,
expected_owner_uid: int = 0,
expected_group_gid: int | None = None,
expected_parent_mode: int = 0o750,
expected_file_mode: int = 0o640,
) -> ServicePathPolicy:
lexical = Path(os.path.abspath(str(path)))
if lexical.is_symlink():
raise PathPolicyError("isolated_writer_path_policy_symlink_rejected")
try:
parent_info = lexical.parent.stat(follow_symlinks=False)
file_info = lexical.stat(follow_symlinks=False)
except FileNotFoundError:
raise PathPolicyError("isolated_writer_path_policy_missing") from None
if stat.S_ISLNK(parent_info.st_mode) or not stat.S_ISDIR(parent_info.st_mode):
raise PathPolicyError("isolated_writer_path_policy_parent_rejected")
if stat.S_ISLNK(file_info.st_mode) or not stat.S_ISREG(file_info.st_mode):
raise PathPolicyError("isolated_writer_path_policy_file_rejected")
if lexical.resolve(strict=True) != lexical:
raise PathPolicyError("isolated_writer_path_policy_symlink_rejected")
if (
parent_info.st_uid != expected_owner_uid
or stat.S_IMODE(parent_info.st_mode) != expected_parent_mode
):
raise PathPolicyError("isolated_writer_path_policy_parent_permissions_rejected")
if (
file_info.st_uid != expected_owner_uid
or stat.S_IMODE(file_info.st_mode) != expected_file_mode
):
raise PathPolicyError("isolated_writer_path_policy_permissions_rejected")
if expected_group_gid is not None and (
parent_info.st_gid != expected_group_gid or file_info.st_gid != expected_group_gid
):
raise PathPolicyError("isolated_writer_path_policy_group_rejected")
if file_info.st_size <= 0 or file_info.st_size > MAX_POLICY_BYTES:
raise PathPolicyError("isolated_writer_path_policy_file_size_rejected")
raw = lexical.read_bytes()
try:
document = json.loads(raw.decode("utf-8"))
except (UnicodeDecodeError, json.JSONDecodeError):
raise PathPolicyError("isolated_writer_path_policy_json_rejected") from None
canonical = _canonical_json(document)
if raw != canonical:
raise PathPolicyError("isolated_writer_path_policy_not_canonical")
return _parse_policy(document, canonical)
@lru_cache(maxsize=1)
def configured_path_policy() -> ServicePathPolicy | None:
configured = os.getenv("AIOS_GITOPS_PATH_POLICY_FILE", "").strip()
if not configured:
return None
if not Path(configured).is_absolute():
raise PathPolicyError("isolated_writer_path_policy_path_rejected")
try:
gitops_gid = grp.getgrnam("gitops").gr_gid
except KeyError:
raise PathPolicyError("isolated_writer_path_policy_group_rejected") from None
loaded = load_path_policy(Path(configured), expected_group_gid=gitops_gid)
if loaded.audience != os.getenv("AIOS_GITOPS_SERVICE_AUDIENCE", ""):
raise PathPolicyError("isolated_writer_path_policy_audience_rejected")
if loaded.repository_identity != os.getenv("AIOS_GITOPS_REPOSITORY_IDENTITY", ""):
raise PathPolicyError("isolated_writer_path_policy_repository_rejected")
if loaded.allowed_branch != os.getenv("AIOS_GITOPS_ALLOWED_BRANCH", ""):
raise PathPolicyError("isolated_writer_path_policy_branch_rejected")
return loaded
def clear_path_policy_cache() -> None:
configured_path_policy.cache_clear()
def require_service_path(operation: str, path: str) -> OperationPolicy:
loaded = configured_path_policy()
if loaded is None:
raise PathPolicyError("isolated_writer_service_path_policy_required")
return loaded.require_exact_path(operation, path)
def configured_path_policy_sha256() -> str | None:
loaded = configured_path_policy()
return None if loaded is None else loaded.sha256
def validate_content(operation: str, path: str, content: str) -> None:
selected = require_service_path(operation, path)
try:
encoded = content.encode("utf-8", errors="strict")
except (AttributeError, UnicodeEncodeError):
raise PathPolicyError("isolated_writer_systemd_profile_rejected") from None
if len(encoded) > selected.max_content_bytes:
raise PathPolicyError("isolated_writer_service_content_too_large")
if selected.content_profile == "systemd-codex-review-worker-v1":
_validate_systemd_codex_review_worker(content)
return
raise PathPolicyError("isolated_writer_path_policy_profile_rejected")
def _validate_systemd_codex_review_worker(content: str) -> None:
if not isinstance(content, str):
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
try:
content.encode("utf-8", errors="strict")
except UnicodeEncodeError:
raise PathPolicyError("isolated_writer_systemd_profile_rejected") from None
if (
"\x00" in content
or "\r" in content
or _SECRET_RE.search(content)
or not content.endswith("\n")
):
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
sections: set[str] = set()
values: dict[tuple[str, str], list[str]] = {}
section: str | None = None
for line in content.splitlines():
if len(line.encode("utf-8")) > _SYSTEMD_MAX_LINE_BYTES:
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
if not line:
continue
if line[0].isspace() or line.startswith(("#", ";")):
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
if line.startswith("[") and line.endswith("]"):
candidate = line[1:-1]
if (
not _SYSTEMD_NAME_RE.fullmatch(candidate)
or candidate not in _SYSTEMD_ALLOWED_DIRECTIVES
or candidate in sections
):
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
sections.add(candidate)
section = candidate
continue
if section is None or "=" not in line:
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
directive, value = line.split("=", 1)
if (
not _SYSTEMD_NAME_RE.fullmatch(directive)
or directive not in _SYSTEMD_ALLOWED_DIRECTIVES[section]
or not value
or value != value.strip()
):
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
key = (section, directive)
if key in values and key not in _SYSTEMD_MULTI_DIRECTIVES:
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
values.setdefault(key, []).append(value)
if sections != set(_SYSTEMD_ALLOWED_DIRECTIVES):
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
if set(values) != set(_SYSTEMD_EXACT_SINGLE_VALUES) | set(
_SYSTEMD_EXACT_MULTI_VALUES
):
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
for key, expected in _SYSTEMD_EXACT_SINGLE_VALUES.items():
if values.get(key) != [expected]:
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
for key, expected in _SYSTEMD_EXACT_MULTI_VALUES.items():
observed = values.get(key, [])
if len(observed) != len(set(observed)) or tuple(observed) != expected:
raise PathPolicyError("isolated_writer_systemd_profile_rejected")
@@ -0,0 +1,241 @@
"""Digest-only, task-scoped token registry for isolated writers."""
from __future__ import annotations
import argparse
import hashlib
import hmac
import json
import os
import grp
import pwd
import secrets
import sqlite3
import stat
import threading
from datetime import datetime, timezone
from pathlib import Path
from typing import Any
_REGISTRY_INIT_LOCK = threading.Lock()
def utc_now() -> str:
return datetime.now(timezone.utc).strftime("%Y-%m-%dT%H:%M:%SZ")
def token_digest(token: str) -> str:
return hashlib.sha256(token.encode("utf-8")).hexdigest()
class TokenRegistry:
def __init__(self, path: Path | str):
self.path = Path(path)
self._prepare()
def _prepare(self) -> None:
self.path.parent.mkdir(parents=True, exist_ok=True)
if self.path.parent.is_symlink() or self.path.is_symlink():
raise PermissionError("writer_token_registry_symlink_rejected")
with _REGISTRY_INIT_LOCK:
with self._connect() as db:
db.executescript(
"""
CREATE TABLE IF NOT EXISTS token_grants (
token_id TEXT PRIMARY KEY,
token_digest TEXT NOT NULL UNIQUE,
grant_json TEXT NOT NULL,
revoked INTEGER NOT NULL DEFAULT 0,
created_at TEXT NOT NULL
);
CREATE TABLE IF NOT EXISTS token_uses (
token_id TEXT NOT NULL,
operation TEXT NOT NULL,
use_count INTEGER NOT NULL DEFAULT 0,
PRIMARY KEY(token_id, operation),
FOREIGN KEY(token_id) REFERENCES token_grants(token_id)
);
"""
)
os.chmod(self.path, 0o600)
def _connect(self) -> sqlite3.Connection:
db = sqlite3.connect(self.path, timeout=30, isolation_level=None)
db.row_factory = sqlite3.Row
db.execute("PRAGMA journal_mode=WAL")
db.execute("PRAGMA synchronous=FULL")
db.execute("PRAGMA foreign_keys=ON")
return db
def issue(self, grant: dict[str, Any], token: str | None = None) -> tuple[str, dict[str, Any]]:
value = token or secrets.token_urlsafe(32)
if len(value.encode("utf-8")) < 32:
raise ValueError("writer_token_entropy_insufficient")
record = dict(grant)
record["schema_version"] = 2
record["token_digest"] = token_digest(value)
record["revoked"] = False
record.setdefault("created_at", utc_now())
required = (
"token_id",
"audience",
"task_id",
"source_cidrs",
"allowed_branch",
"approved_base_oid",
"allowed_operations",
"allowed_paths",
"not_before",
"expires_at",
"max_uses",
"issued_by",
)
if any(not record.get(field) for field in required):
raise ValueError("writer_token_grant_incomplete")
encoded = json.dumps(record, sort_keys=True, separators=(",", ":"))
with self._connect() as db:
db.execute("BEGIN IMMEDIATE")
try:
db.execute(
"""
INSERT INTO token_grants(token_id, token_digest, grant_json, revoked, created_at)
VALUES(?,?,?,?,?)
""",
(
str(record["token_id"]),
str(record["token_digest"]),
encoded,
0,
str(record["created_at"]),
),
)
db.execute("COMMIT")
except Exception:
db.execute("ROLLBACK")
raise
return value, record
def find(self, token: str) -> dict[str, Any] | None:
candidate = token_digest(token)
with self._connect() as db:
rows = db.execute(
"SELECT token_digest, grant_json, revoked FROM token_grants"
).fetchall()
match = None
for row in rows:
if hmac.compare_digest(str(row["token_digest"]), candidate):
match = dict(json.loads(str(row["grant_json"])))
match["revoked"] = bool(row["revoked"])
return match
def consume(self, token_id: str, operation: str, maximum: int) -> int:
if maximum < 1:
raise PermissionError("writer_token_operation_exhausted")
with self._connect() as db:
db.execute("BEGIN IMMEDIATE")
try:
row = db.execute(
"SELECT revoked FROM token_grants WHERE token_id=?",
(token_id,),
).fetchone()
if row is None or bool(row["revoked"]):
raise PermissionError("writer_token_revoked")
used_row = db.execute(
"SELECT use_count FROM token_uses WHERE token_id=? AND operation=?",
(token_id, operation),
).fetchone()
used = int(used_row["use_count"]) if used_row else 0
if used >= maximum:
raise PermissionError("writer_token_operation_exhausted")
current = used + 1
db.execute(
"""
INSERT INTO token_uses(token_id, operation, use_count)
VALUES(?,?,?)
ON CONFLICT(token_id, operation)
DO UPDATE SET use_count=excluded.use_count
""",
(token_id, operation, current),
)
db.execute("COMMIT")
return current
except Exception:
db.execute("ROLLBACK")
raise
def revoke(self, token_id: str) -> bool:
with self._connect() as db:
db.execute("BEGIN IMMEDIATE")
changed = db.execute(
"UPDATE token_grants SET revoked=1 WHERE token_id=? AND revoked=0",
(token_id,),
).rowcount
db.execute("COMMIT")
return bool(changed)
def usage(self, token_id: str, operation: str) -> int:
with self._connect() as db:
row = db.execute(
"SELECT use_count FROM token_uses WHERE token_id=? AND operation=?",
(token_id, operation),
).fetchone()
return int(row["use_count"]) if row else 0
def _write_secret_file(
path: Path,
token: str,
*,
owner: str | None = None,
group: str | None = None,
) -> None:
path.parent.mkdir(parents=True, exist_ok=True)
if path.parent.is_symlink() or path.is_symlink():
raise PermissionError("writer_token_file_symlink_rejected")
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
if hasattr(os, "O_NOFOLLOW"):
flags |= os.O_NOFOLLOW
fd = os.open(path, flags, 0o600)
try:
if not stat.S_ISREG(os.fstat(fd).st_mode):
raise PermissionError("writer_token_file_not_regular")
if owner is not None or group is not None:
uid = pwd.getpwnam(owner).pw_uid if owner is not None else -1
gid = grp.getgrnam(group).gr_gid if group is not None else -1
os.fchown(fd, uid, gid)
os.write(fd, token.encode("utf-8"))
os.fsync(fd)
finally:
os.close(fd)
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--registry", required=True)
sub = parser.add_subparsers(dest="command", required=True)
issue = sub.add_parser("issue")
issue.add_argument("--grant-file", required=True)
issue.add_argument("--token-file", required=True)
issue.add_argument("--owner")
issue.add_argument("--group")
revoke = sub.add_parser("revoke")
revoke.add_argument("--token-id", required=True)
args = parser.parse_args(argv)
registry = TokenRegistry(args.registry)
if args.command == "issue":
grant = json.loads(Path(args.grant_file).read_text(encoding="utf-8"))
token, record = registry.issue(grant)
_write_secret_file(
Path(args.token_file),
token,
owner=args.owner,
group=args.group,
)
print(json.dumps({"token_id": record["token_id"], "created": True}, sort_keys=True))
return 0
changed = registry.revoke(args.token_id)
print(json.dumps({"token_id": args.token_id, "revoked": changed}, sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1 +0,0 @@
"""Isolated, Shadow-attested Codex Task Plane Worker components."""
@@ -1,212 +0,0 @@
"""Shadow-only Codex read/review/test worker lifecycle and CLI."""
from __future__ import annotations
import argparse
import json
import os
import threading
import time
from dataclasses import dataclass
from datetime import datetime, timezone
from pathlib import Path
from typing import Any, Callable
from .result_attestation import TaskResultEnvelope, TrustPolicy, task_result_envelope
from .task_client import CredentialSource, StageAClientConfig, TaskPlaneClient
MAX_CONCURRENCY = 1
HEARTBEAT_INTERVAL_SECONDS = 15
CLAIM_LEASE_SECONDS = 120
SHADOW_ONLY = True
DEFAULT_TRUST_LEVEL = TrustPolicy.SHADOW_ATTESTED
DEFAULT_PRODUCTION_TRUST = False
READONLY_CAPABILITIES = ("code.read", "test.python", "review.security")
class CodexReviewTaskError(ValueError):
pass
@dataclass(frozen=True)
class CodexReviewTaskPolicy:
worker_id: str
identity: str
trust_zone: str = "isolated-review"
max_concurrency: int = MAX_CONCURRENCY
heartbeat_interval_seconds: int = HEARTBEAT_INTERVAL_SECONDS
claim_lease_seconds: int = CLAIM_LEASE_SECONDS
shadow_only: bool = SHADOW_ONLY
def registration_payload(self) -> dict[str, object]:
return {
"worker_id": self.worker_id, "worker_type": "codex-review",
"identity": self.identity, "owner_identity": self.identity,
"capabilities": list(READONLY_CAPABILITIES), "trust_zone": self.trust_zone,
"max_concurrency": self.max_concurrency,
"heartbeat_interval_seconds": self.heartbeat_interval_seconds,
"supported_protocols": ["aios-task-v1"], "registration_policy": "self",
}
def assert_shadow_only_task(self, task: dict[str, Any]) -> None:
plan = task.get("plan", task)
metadata = plan.get("metadata", {}) if isinstance(plan, dict) else {}
required = set(plan.get("required_capabilities", [])) if isinstance(plan, dict) else set()
if self.max_concurrency != 1 or self.heartbeat_interval_seconds != 15 or self.claim_lease_seconds != 120:
raise CodexReviewTaskError("worker timing/concurrency contract rejected")
if not isinstance(plan, dict) or metadata.get("production_side_effects") is not False:
raise CodexReviewTaskError("task must declare production_side_effects=false")
if plan.get("risk") != "low" or plan.get("task_type") not in {"code.review", "test.execute", None}:
raise CodexReviewTaskError("task risk or type rejected")
if plan.get("data_classification", "internal") not in {"public", "internal"}:
raise CodexReviewTaskError("task classification rejected")
if not required.issubset(set(READONLY_CAPABILITIES)):
raise CodexReviewTaskError("task capability rejected")
if any(value.startswith(("code.write", "deploy", "secret", "production")) for value in required):
raise CodexReviewTaskError("side-effect capability rejected")
def default_result_envelope(self, *, task_id: str, claim_id: str, worker_identity: str) -> TaskResultEnvelope:
return task_result_envelope(
task_id=task_id, claim_id=claim_id, worker_id=self.worker_id,
worker_identity=worker_identity, status="CREATED", outputs=[], evidence=[],
started_at="1970-01-01T00:00:00Z", completed_at="1970-01-01T00:00:00Z",
)
class _LeaseGuard:
def __init__(self, client: TaskPlaneClient, task_id: str, claim_id: str) -> None:
self.client, self.task_id, self.claim_id = client, task_id, claim_id
self.stop_event = threading.Event()
self.lost = threading.Event()
self.thread = threading.Thread(target=self._run, daemon=True)
def _run(self) -> None:
while not self.stop_event.wait(HEARTBEAT_INTERVAL_SECONDS):
try:
self.client.claim_heartbeat(self.task_id, claim_id=self.claim_id, lease_seconds=CLAIM_LEASE_SECONDS)
except Exception:
self.lost.set()
self.stop_event.set()
def __enter__(self) -> "_LeaseGuard":
self.thread.start()
return self
def __exit__(self, *_: object) -> None:
self.stop_event.set()
self.thread.join(timeout=2)
def require_active(self) -> None:
if self.lost.is_set():
raise CodexReviewTaskError("claim lease lost")
class CodexReviewWorker:
def __init__(self, client: TaskPlaneClient, policy: CodexReviewTaskPolicy, source_commit: str) -> None:
self.client, self.policy, self.source_commit = client, policy, source_commit
def register(self) -> dict[str, Any]:
return self.client.register_worker(**{
"worker_id": self.policy.worker_id, "worker_type": "codex-review",
"identity": self.policy.identity, "capabilities": READONLY_CAPABILITIES,
"trust_zone": self.policy.trust_zone, "max_concurrency": 1,
"heartbeat_interval_seconds": 15,
})
def poll_safe_task(self) -> dict[str, Any] | None:
for task in self.client.list_tasks():
if task.get("status") not in {"CREATED", "QUEUED", "FAILED_RECOVERABLE"}:
continue
try:
full = self.client.get_task(str(task["task_id"]))
self.policy.assert_shadow_only_task(full)
return full
except (KeyError, CodexReviewTaskError):
continue
return None
def run_once(self, executor: Callable[[dict[str, Any], Callable[[float, str], None]], tuple[str, list[dict[str, Any]], list[dict[str, Any]]]]) -> str | None:
self.register()
task = self.poll_safe_task()
if task is None:
return None
task_id = str(task["task_id"])
claim = self.client.claim(task_id, worker_id=self.policy.worker_id, lease_seconds=120)
claim_id = str(claim["claim_id"])
started = datetime.now(timezone.utc).isoformat()
with _LeaseGuard(self.client, task_id, claim_id) as guard:
def emit(value: float, stage: str) -> None:
guard.require_active()
self.client.progress(task_id, claim_id=claim_id, progress=value, stage=stage)
summary, outputs, evidence = executor(task, emit)
guard.require_active()
completed = datetime.now(timezone.utc).isoformat()
envelope = task_result_envelope(
task_id=task_id, claim_id=claim_id,
task_revision=int(claim["task_revision"]),
worker_id=self.policy.worker_id, worker_identity=self.policy.identity,
operation_digest=str(claim["operation_digest"]),
source_commit=self.source_commit, status="COMPLETED", summary=summary,
outputs=outputs, evidence=evidence, started_at=started, completed_at=completed,
)
guard.require_active()
envelope_payload = envelope.to_dict()
self.client.result(
task_id,
claim_id=claim_id,
status=str(envelope_payload["status"]),
outputs=list(envelope_payload["outputs"]),
evidence=list(envelope_payload["evidence"]),
started_at=str(envelope_payload["started_at"]),
completed_at=str(envelope_payload["completed_at"]),
trust_level=TrustPolicy.SHADOW_ATTESTED.value,
production_trust=False,
)
return task_id
def build_default_task_policy(worker_id: str, worker_identity: str) -> CodexReviewTaskPolicy:
return CodexReviewTaskPolicy(worker_id=worker_id, identity=worker_identity)
def make_shadow_result_payload(*, task_id: str, claim_id: str, worker_identity: str) -> TaskResultEnvelope:
return task_result_envelope(
task_id=task_id, claim_id=claim_id, worker_identity=worker_identity,
status="COMPLETED", outputs=[], evidence=[],
started_at="1970-01-01T00:00:00Z", completed_at="1970-01-01T00:00:00Z",
)
def _assert_disabled_production() -> None:
for name in ("AIOS_GITOPS_WRITES_ENABLED", "AIOS_SILENT_RELEASE_EXECUTION_ENABLED", "AIOS_TASK_PLANE_EXECUTION_ENABLED"):
if os.environ.get(name, "false").lower() != "false":
raise CodexReviewTaskError(f"{name} must remain false")
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--self-check", action="store_true")
parser.add_argument("--once", action="store_true")
args = parser.parse_args(argv)
_assert_disabled_production()
config = StageAClientConfig(os.environ.get("AIOS_TASK_PLANE_ENDPOINT", "http://127.0.0.1:18923"))
if args.self_check:
print(json.dumps({"status": "PASS", "shadow_only": True, "production_trust": False}, sort_keys=True))
return 0
if os.environ.get("AIOS_CODEX_WORKER_SHADOW_CANARY_ENABLED", "false").lower() != "true":
raise SystemExit("Codex worker execution is disabled")
credential = CredentialSource(Path(os.environ["AIOS_TASK_PLANE_WORKER_TOKEN_FILE"])).read_token()
source_commit = os.environ.get("AIOS_CODEX_WORKER_SOURCE_COMMIT", "")
policy = CodexReviewTaskPolicy(
worker_id=os.environ["AIOS_CODEX_WORKER_ID"],
identity=os.environ["AIOS_CODEX_WORKER_IDENTITY"],
)
worker = CodexReviewWorker(TaskPlaneClient(config, credential), policy, source_commit)
if args.once:
worker.run_once(lambda _task, emit: (emit(100, "VERIFIED") or ("shadow self-check", [], [])))
return 0
raise SystemExit("continuous real worker execution is not enabled")
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,62 +0,0 @@
"""Fail-closed command and environment policy for the isolated Codex Worker."""
from __future__ import annotations
import os
import re
import subprocess
from pathlib import Path
OID_RE = re.compile(r"[0-9a-f]{40}")
DENIED_ENV = ("TOKEN", "PASSWORD", "SECRET", "CREDENTIAL", "AUTHORIZATION", "COOKIE", "PRIVATE_KEY", "AWS_", "GITHUB_", "GITEA_")
class CommandPolicyError(ValueError):
pass
def isolated_environment(home: Path, temp_root: Path, pythonpath: str) -> dict[str, str]:
home.mkdir(mode=0o700, parents=True, exist_ok=True)
temp_root.mkdir(mode=0o700, parents=True, exist_ok=True)
allowed = {key: value for key, value in os.environ.items() if key in {"PATH", "LANG", "LC_ALL"}}
allowed.update({"HOME": str(home), "TMPDIR": str(temp_root), "PYTHONPATH": pythonpath, "PYTHONDONTWRITEBYTECODE": "1"})
if any(any(marker in key.upper() for marker in DENIED_ENV) for key in allowed):
raise CommandPolicyError("secret environment retained")
return allowed
class CommandPolicy:
def __init__(self, repo: Path, result_root: Path, *, timeout_seconds: int = 300, output_limit: int = 1_000_000):
self.repo = repo.resolve()
self.result_root = result_root.resolve()
self.timeout_seconds = timeout_seconds
self.output_limit = output_limit
def _oid(self, value: str) -> str:
if not OID_RE.fullmatch(value):
raise CommandPolicyError("exact commit oid required")
return value
def build(self, kind: str, *, oid: str, paths: list[str] | None = None, output: Path | None = None) -> list[str]:
oid = self._oid(oid)
paths = paths or []
if any(not path or path.startswith("-") or Path(path).is_absolute() or ".." in Path(path).parts for path in paths):
raise CommandPolicyError("invalid allowlisted path")
if kind == "diff-check":
return ["git", "-C", str(self.repo), "diff", "--check"]
if kind == "git-show" and len(paths) == 1:
return ["git", "-C", str(self.repo), "show", f"{oid}:{paths[0]}"]
if kind == "pytest" and paths and all(path.startswith("tests/task_plane/") or path == "tests/test_isolated_writer_policy.py" for path in paths):
return ["python3", "-m", "pytest", "-q", *paths]
if kind == "compileall" and paths and all(path.startswith(("active-runtime/app/task_plane", "runtime/agent-os")) for path in paths):
return ["python3", "-m", "compileall", "-q", *paths]
if kind == "acceptance" and output is not None:
target = output.resolve()
if target.parent != self.result_root:
raise CommandPolicyError("output escapes result root")
return ["bash", "scripts/task-plane/run_task_plane_acceptance.sh", str(target)]
raise CommandPolicyError("command template not allowlisted")
def run(self, argv: list[str], env: dict[str, str]) -> tuple[int, str]:
completed = subprocess.run(argv, cwd=self.repo, env=env, stdin=subprocess.DEVNULL, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True, timeout=self.timeout_seconds, start_new_session=True, check=False)
output = completed.stdout[: self.output_limit]
return completed.returncode, output
@@ -1,56 +0,0 @@
"""Bounded progress payload helpers."""
from __future__ import annotations
import math
from dataclasses import dataclass
from typing import Any
@dataclass(frozen=True)
class ProgressEnvelope:
claim_id: str
progress: int | float
stage: str
lease_seconds: int = 120
message: str | None = None
def validate(self) -> None:
if not self.claim_id:
raise ValueError("claim_id is required")
numeric = float(self.progress)
if not math.isfinite(numeric) or not 0 <= numeric <= 100:
raise ValueError("progress must be finite and within [0, 100]")
if not 1 <= self.lease_seconds <= 3600:
raise ValueError("lease_seconds out of range")
if not self.stage or len(self.stage) > 64 or any(ord(ch) < 32 for ch in self.stage):
raise ValueError("stage is invalid")
if self.message is not None and len(self.message) > 512:
raise ValueError("message is too long")
def as_request(self) -> dict[str, Any]:
self.validate()
return {
"claim_id": self.claim_id, "progress": float(self.progress),
"stage": self.stage, "lease_seconds": self.lease_seconds,
"message": self.message,
}
def clamp_progress(value: float) -> float:
numeric = float(value)
if not math.isfinite(numeric):
raise ValueError("progress must be finite")
return max(0.0, min(100.0, numeric))
def safe_stage_name(stage: str | None) -> str:
value = str(stage or "").strip()
if not value:
return "RUNNING"
if any(ord(ch) < 32 for ch in value):
raise ValueError("stage is invalid")
return value[:64]
def build_progress_payload(*, claim_id: str, progress: float, stage: str = "RUNNING", lease_seconds: int = 120, message: str | None = None) -> dict[str, Any]:
return ProgressEnvelope(claim_id, clamp_progress(progress), safe_stage_name(stage), lease_seconds, message).as_request()
@@ -1,157 +0,0 @@
"""Canonical, Shadow-only result envelopes for the Codex review worker."""
from __future__ import annotations
import hashlib
import hmac
import json
import re
from dataclasses import dataclass
from enum import StrEnum
from typing import Any
OID_RE = re.compile(r"^[0-9a-f]{40}$")
SHA256_RE = re.compile(r"^[0-9a-f]{64}$")
class TrustPolicy(StrEnum):
SHADOW_ATTESTED = "SHADOW_ATTESTED"
SHADOW_UNATTESTED = "SHADOW_UNATTESTED"
def _canonical_sha256(payload: object) -> str:
encoded = json.dumps(
payload, ensure_ascii=False, sort_keys=True, separators=(",", ":")
).encode("utf-8")
return hashlib.sha256(encoded).hexdigest()
@dataclass(frozen=True)
class TaskResultEnvelope:
task_id: str
claim_id: str
worker_identity: str
status: str
outputs: list[dict[str, Any]]
evidence: list[dict[str, Any]]
started_at: str
completed_at: str
task_revision: int = 1
worker_id: str = ""
operation_digest: str = ""
source_commit: str = "0" * 40
summary: str = ""
evidence_digests: tuple[str, ...] = ()
result_digest: str | None = None
trust_level: TrustPolicy = TrustPolicy.SHADOW_ATTESTED
production_trust: bool = False
signature: str | None = None
attestation_ref: str | None = None
def digest_payload(self) -> dict[str, Any]:
return {
"task_id": self.task_id,
"claim_id": self.claim_id,
"task_revision": self.task_revision,
"worker_id": self.worker_id,
"worker_identity": self.worker_identity,
"operation_digest": self.operation_digest,
"source_commit": self.source_commit,
"status": self.status,
"summary": self.summary,
"outputs": self.outputs,
"evidence": self.evidence,
"evidence_digests": list(self.evidence_digests),
"started_at": self.started_at,
"completed_at": self.completed_at,
"trust_level": TrustPolicy.SHADOW_ATTESTED.value,
"production_trust": False,
"attestation_ref": self.attestation_ref,
}
def computed_digest(self) -> str:
return _canonical_sha256(self.digest_payload())
def validate(self) -> None:
required = {
"task_id": self.task_id,
"claim_id": self.claim_id,
"worker_id": self.worker_id,
"worker_identity": self.worker_identity,
"operation_digest": self.operation_digest,
"status": self.status,
"started_at": self.started_at,
"completed_at": self.completed_at,
}
if any(not str(value).strip() for value in required.values()):
raise ValueError("result envelope required field missing")
if self.task_revision < 1:
raise ValueError("task_revision must be positive")
if not OID_RE.fullmatch(self.source_commit):
raise ValueError("source_commit must be a full commit OID")
if not SHA256_RE.fullmatch(self.operation_digest):
raise ValueError("operation_digest must be SHA-256")
if any(not SHA256_RE.fullmatch(value) for value in self.evidence_digests):
raise ValueError("evidence digest must be SHA-256")
observed = tuple(_canonical_sha256(item) for item in self.evidence)
if observed != self.evidence_digests:
raise ValueError("evidence digest binding mismatch")
if self.trust_level is not TrustPolicy.SHADOW_ATTESTED:
raise ValueError("Codex review results must remain SHADOW_ATTESTED")
if self.production_trust is not False:
raise ValueError("production_trust is forbidden")
if self.result_digest is not None and not hmac.compare_digest(
self.result_digest, self.computed_digest()
):
raise ValueError("result digest mismatch")
def finalized(self) -> "TaskResultEnvelope":
from dataclasses import replace
envelope = replace(self, result_digest=self.computed_digest())
envelope.validate()
return envelope
def to_dict(self) -> dict[str, Any]:
envelope = self if self.result_digest is not None else self.finalized()
envelope.validate()
return {**envelope.digest_payload(), "result_digest": envelope.result_digest}
def task_result_envelope(
*,
task_id: str,
claim_id: str,
worker_identity: str,
status: str,
outputs: list[dict[str, Any]],
evidence: list[dict[str, Any]],
started_at: str,
completed_at: str,
task_revision: int = 1,
worker_id: str | None = None,
operation_digest: str | None = None,
source_commit: str = "0" * 40,
summary: str = "",
trust_level: TrustPolicy = TrustPolicy.SHADOW_ATTESTED,
production_trust: bool = False,
) -> TaskResultEnvelope:
evidence_digests = tuple(_canonical_sha256(item) for item in evidence)
envelope = TaskResultEnvelope(
task_id=task_id,
claim_id=claim_id,
task_revision=task_revision,
worker_id=worker_id or worker_identity,
worker_identity=worker_identity,
operation_digest=operation_digest or ("0" * 64),
source_commit=source_commit,
status=status,
summary=summary,
outputs=outputs,
evidence=evidence,
evidence_digests=evidence_digests,
started_at=started_at,
completed_at=completed_at,
trust_level=trust_level,
production_trust=production_trust,
)
return envelope.finalized()
@@ -1,138 +0,0 @@
"""Fixed-command, no-shell runner for a read-only Codex workspace."""
from __future__ import annotations
import os
import re
import signal
import subprocess
from dataclasses import dataclass
from pathlib import Path, PurePosixPath
from .command_policy import CommandPolicyError
from .workspace import WorkspacePermissionError, assert_private_path
OID_RE = re.compile(r"^[0-9a-f]{40}$")
FORBIDDEN_SNIPPETS = ("http://", "https://", ";", "&&", "||", "|", "`", "${", "$(")
class CommandRunnerError(ValueError):
pass
class CommandDisallowedError(CommandRunnerError):
pass
class CommandPolicyViolation(CommandRunnerError):
pass
@dataclass(frozen=True)
class CommandResult:
returncode: int
output: str
class SafeCommandRunner:
allowed_kinds = ("git-diff", "diff-check", "git-show", "pytest", "compileall", "acceptance")
def __init__(self, repo: Path, result_root: Path, *, policy=None, timeout_seconds: int = 300, output_limit: int = 1_000_000) -> None:
self.repo = assert_private_path(repo)
self.result_root = assert_private_path(result_root)
self.timeout_seconds, self.output_limit = timeout_seconds, output_limit
@staticmethod
def _oid(value: str) -> str:
if not OID_RE.fullmatch(str(value)):
raise CommandPolicyError("exact commit oid required")
return value
@staticmethod
def _forbidden(value: str) -> bool:
lowered = value.lower()
return (
re.search(r"\b(?:bash|eval)\b", lowered) is not None
or re.search(r"(^|\s)-c(\s|$)", lowered) is not None
or any(marker in value for marker in FORBIDDEN_SNIPPETS)
)
def _path(self, value: str, *, allowed_prefixes: tuple[str, ...]) -> str:
if not value or value.startswith("-") or "\\" in value or self._forbidden(value):
raise CommandDisallowedError("unsafe path input")
pure = PurePosixPath(value)
if pure.is_absolute() or any(part in {"", ".", ".."} for part in pure.parts):
raise CommandPolicyError("path traversal is forbidden")
if not any(value == prefix or value.startswith(prefix + "/") for prefix in allowed_prefixes):
raise CommandPolicyError("path outside allowlist")
try:
candidate = assert_private_path(self.repo / value)
except WorkspacePermissionError as exc:
raise CommandPolicyError("symlink path is forbidden") from exc
try:
candidate.relative_to(self.repo)
except ValueError:
raise CommandPolicyError("path escapes repository") from None
return value
def _output(self, output: Path) -> Path:
if Path(output).is_absolute() or Path(output).name != str(output):
raise CommandPolicyError("output must be a direct result file")
target = assert_private_path(self.result_root / output)
try:
target.relative_to(self.result_root)
except ValueError:
raise CommandPolicyError("output escapes result root") from None
return target
def build(self, kind: str, *, oid: str, other_oid: str | None = None, paths: list[str] | None = None, output: Path | None = None) -> list[str]:
if kind not in self.allowed_kinds:
raise CommandDisallowedError("command kind not allowed")
first = self._oid(oid)
values = paths or []
if kind == "git-diff":
second = self._oid(str(other_oid or ""))
return ["git", "-C", str(self.repo), "diff", "--no-ext-diff", "--no-textconv", first, second]
if kind == "diff-check":
return ["git", "-C", str(self.repo), "diff", "--check"]
if kind == "git-show" and len(values) == 1:
path = self._path(values[0], allowed_prefixes=("active-runtime", "runtime", "scripts", "tests", "docs"))
return ["git", "-C", str(self.repo), "show", f"{first}:{path}"]
if kind == "pytest" and values:
safe = [self._path(value, allowed_prefixes=("tests/task_plane", "tests/test_isolated_writer_policy.py")) for value in values]
return ["python3", "-m", "pytest", "-q", *safe]
if kind == "compileall" and values:
safe = [self._path(value, allowed_prefixes=("active-runtime/app/task_plane", "runtime/agent-os")) for value in values]
return ["python3", "-m", "compileall", "-q", *safe]
if kind == "acceptance" and output is not None and not values:
return ["bash", "scripts/task-plane/run_task_plane_acceptance.sh", str(self._output(output))]
raise CommandPolicyError("command template not allowlisted")
def run(self, kind: str, *, oid: str, other_oid: str | None = None, paths: list[str] | None = None, output: Path | None = None, env: dict[str, str] | None = None) -> CommandResult:
if env and any(marker in key.upper() for key in env for marker in ("TOKEN", "SECRET", "PASSWORD", "CREDENTIAL", "AUTHORIZATION", "COOKIE", "PRIVATE_KEY")):
raise CommandPolicyViolation("secret environment rejected")
command = self.build(kind, oid=oid, other_oid=other_oid, paths=paths, output=output)
safe_env = {
"HOME": str(self.result_root),
"PATH": os.environ.get("PATH", ""),
"LANG": "C.UTF-8",
"PYTHONDONTWRITEBYTECODE": "1",
"GIT_CONFIG_NOSYSTEM": "1",
"GIT_TERMINAL_PROMPT": "0",
}
process = subprocess.Popen(
command, cwd=self.repo, env=safe_env, stdin=subprocess.DEVNULL,
stdout=subprocess.PIPE, stderr=subprocess.STDOUT, text=True,
start_new_session=True,
)
try:
text, _ = process.communicate(timeout=self.timeout_seconds)
except subprocess.TimeoutExpired:
os.killpg(process.pid, signal.SIGKILL)
text, _ = process.communicate()
raise CommandRunnerError("command timeout")
return CommandResult(process.returncode, text[: self.output_limit])
Runner = SafeCommandRunner
FixedCommandRunner = SafeCommandRunner
CommandResultEnvelope = CommandResult
@@ -1,300 +0,0 @@
"""Fail-closed loopback HTTP client for the Codex review worker."""
from __future__ import annotations
import hashlib
import json
import os
import re
import stat
import time
import urllib.error
import urllib.parse
import urllib.request
from dataclasses import dataclass
from pathlib import Path
from typing import Any, Iterable
MAX_HTTP_BODY_BYTES = 1_000_000
_RETRYABLE_STATUS = {429, 503}
_RETRY_BACKOFF_SECONDS = (0.25, 0.5, 1.0, 2.0)
_IDENTIFIER_RE = re.compile(r"^[A-Za-z0-9][A-Za-z0-9._:-]{0,127}$")
class TaskClientError(RuntimeError):
pass
class TaskClientProtocolError(TaskClientError):
pass
class TaskClientAuthError(TaskClientError):
pass
class TaskClientResponseTooLargeError(TaskClientError):
pass
def _safe_identifier(value: str, name: str) -> str:
candidate = str(value or "")
if not _IDENTIFIER_RE.fullmatch(candidate):
raise TaskClientProtocolError(f"invalid {name}")
return urllib.parse.quote(candidate, safe="")
def _stable_key(operation: str, payload: object) -> str:
encoded = json.dumps(
payload, ensure_ascii=False, sort_keys=True, separators=(",", ":")
).encode("utf-8")
return f"codex-worker:{operation}:{hashlib.sha256(encoded).hexdigest()}"
@dataclass(frozen=True)
class CredentialSource:
token_path: Path
token_owner: str = "aiman"
token_group: str = "gitops"
expected_mode: int = 0o600
def read_token(self) -> str:
import grp
import pwd
path = Path(self.token_path)
flags = os.O_RDONLY
if hasattr(os, "O_NOFOLLOW"):
flags |= os.O_NOFOLLOW
try:
fd = os.open(path, flags)
except OSError as exc:
raise TaskClientAuthError("credential file unavailable") from exc
try:
info = os.fstat(fd)
if not stat.S_ISREG(info.st_mode):
raise TaskClientAuthError("credential file must be regular")
if stat.S_IMODE(info.st_mode) != self.expected_mode:
raise TaskClientAuthError("credential file mode rejected")
try:
owner = pwd.getpwuid(info.st_uid).pw_name
group = grp.getgrgid(info.st_gid).gr_name
except KeyError as exc:
raise TaskClientAuthError("credential ownership unresolved") from exc
if owner != self.token_owner or group != self.token_group:
raise TaskClientAuthError("credential ownership rejected")
value = os.read(fd, 4097)
if len(value) > 4096:
raise TaskClientAuthError("credential file too large")
token = value.decode("utf-8", errors="strict").strip()
if len(token.encode("utf-8")) < 32:
raise TaskClientAuthError("credential unavailable")
return token
finally:
os.close(fd)
@dataclass(frozen=True)
class StageAClientConfig:
base_url: str = "http://127.0.0.1:18923"
timeout_seconds: float = 12.0
max_request_bytes: int = MAX_HTTP_BODY_BYTES
max_response_bytes: int = MAX_HTTP_BODY_BYTES
max_retry_attempts: int = 4
default_lease_seconds: int = 120
default_worker_heartbeat_interval_seconds: int = 15
default_max_concurrency: int = 1
def __post_init__(self) -> None:
parsed = urllib.parse.urlsplit(self.base_url)
if (
parsed.scheme != "http"
or parsed.hostname not in {"127.0.0.1", "::1"}
or parsed.username is not None
or parsed.password is not None
or parsed.query
or parsed.fragment
or parsed.path not in {"", "/"}
or parsed.port is None
):
raise ValueError("Task Plane endpoint must be explicit loopback HTTP")
class TaskPlaneClient:
def __init__(self, config: StageAClientConfig, token: str) -> None:
if len(str(token).encode("utf-8")) < 16:
raise TaskClientAuthError("credential is required")
self.config = config
self.__token = str(token)
def __repr__(self) -> str:
return f"TaskPlaneClient(base_url={self.config.base_url!r}, credential=<redacted>)"
def _encode(self, payload: dict[str, Any] | None) -> bytes | None:
if payload is None:
return None
body = json.dumps(payload, ensure_ascii=False, separators=(",", ":")).encode("utf-8")
if len(body) > self.config.max_request_bytes:
raise TaskClientResponseTooLargeError("request payload exceeds configured limit")
return body
def _read_response(self, handle: Any) -> tuple[int, Any]:
status_code = int(getattr(handle, "status", 200))
raw = handle.read(self.config.max_response_bytes + 1)
if len(raw) > self.config.max_response_bytes:
raise TaskClientResponseTooLargeError("response payload exceeds configured limit")
if not raw:
return status_code, {}
try:
return status_code, json.loads(raw.decode("utf-8"))
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
raise TaskClientProtocolError("response is not valid JSON") from exc
def _request(
self,
method: str,
path: str,
payload: dict[str, Any] | None = None,
*,
idempotency_key: str | None = None,
) -> tuple[int, Any]:
if not path.startswith("/") or "//" in path or "?" in path or "#" in path:
raise TaskClientProtocolError("invalid API path")
body = self._encode(payload)
attempts = max(1, min(self.config.max_retry_attempts, 4))
for index in range(attempts):
headers = {"Authorization": f"Bearer {self.__token}", "Accept": "application/json"}
if body is not None:
headers["Content-Type"] = "application/json"
if idempotency_key:
headers["Idempotency-Key"] = idempotency_key
request = urllib.request.Request(
f"{self.config.base_url.rstrip('/')}{path}",
method=method,
data=body,
headers=headers,
)
try:
with urllib.request.urlopen(request, timeout=self.config.timeout_seconds) as response:
return self._read_response(response)
except urllib.error.HTTPError as exc:
status_code, response = self._read_response(exc)
if status_code in {401, 403}:
raise TaskClientAuthError(f"request rejected: HTTP {status_code}")
if status_code in _RETRYABLE_STATUS and index + 1 < attempts:
time.sleep(_RETRY_BACKOFF_SECONDS[index])
continue
code = response.get("error") if isinstance(response, dict) else "request_failed"
raise TaskClientProtocolError(f"request failed: HTTP {status_code} ({code})")
except urllib.error.URLError as exc:
if index + 1 < attempts:
time.sleep(_RETRY_BACKOFF_SECONDS[index])
continue
raise TaskClientProtocolError("request transport error") from exc
raise TaskClientProtocolError("request failed")
def _post(self, path: str, payload: dict[str, Any], *, idempotency_key: str | None = None) -> dict[str, Any]:
status_code, response = self._request(
"POST", path, payload, idempotency_key=idempotency_key or _stable_key(path, payload)
)
if status_code not in {200, 201} or not isinstance(response, dict):
raise TaskClientProtocolError("unexpected API response")
return response
def _get(self, path: str) -> Any:
status_code, response = self._request("GET", path)
if status_code != 200:
raise TaskClientProtocolError("unexpected API response")
return response
def list_tasks(self) -> list[dict[str, Any]]:
response = self._get("/tasks")
if not isinstance(response, list) or any(not isinstance(item, dict) for item in response):
raise TaskClientProtocolError("invalid task list")
return response
def get_task(self, task_id: str) -> dict[str, Any]:
response = self._get(f"/tasks/{_safe_identifier(task_id, 'task_id')}")
if not isinstance(response, dict):
raise TaskClientProtocolError("invalid task response")
return response
def register_worker(
self, *, worker_id: str, worker_type: str, identity: str,
capabilities: Iterable[str], trust_zone: str, max_concurrency: int,
heartbeat_interval_seconds: int, supported_protocols: Iterable[str] = ("aios-task-v1",),
) -> dict[str, Any]:
payload = {
"worker_id": worker_id, "worker_type": worker_type, "identity": identity,
"capabilities": sorted(set(capabilities)), "trust_zone": trust_zone,
"max_concurrency": max_concurrency,
"heartbeat_interval_seconds": heartbeat_interval_seconds,
"supported_protocols": list(supported_protocols),
"owner_identity": identity, "registration_policy": "self",
}
return self._post("/workers/register", payload, idempotency_key=_stable_key("register", payload))
def worker_heartbeat(self, worker_id: str, *, heartbeat_interval_seconds: int | None = None) -> dict[str, Any]:
payload = {} if heartbeat_interval_seconds is None else {"heartbeat_interval_seconds": heartbeat_interval_seconds}
return self._post(f"/workers/{_safe_identifier(worker_id, 'worker_id')}/heartbeat", payload)
def claim(self, task_id: str, *, worker_id: str, lease_seconds: int | None = None) -> dict[str, Any]:
payload = {"worker_id": worker_id, "lease_seconds": lease_seconds or self.config.default_lease_seconds}
return self._post(f"/tasks/{_safe_identifier(task_id, 'task_id')}/claim", payload)
def claim_heartbeat(self, task_id: str, *, claim_id: str, lease_seconds: int | None = None) -> dict[str, Any]:
if not claim_id:
raise TaskClientProtocolError("claim_id is required")
payload = {"claim_id": claim_id, "lease_seconds": lease_seconds or self.config.default_lease_seconds}
return self._post(f"/tasks/{_safe_identifier(task_id, 'task_id')}/heartbeat", payload)
def progress(self, task_id: str, *, claim_id: str, progress: int | float, stage: str, message: str | None = None, lease_seconds: int | None = None) -> dict[str, Any]:
if not claim_id:
raise TaskClientProtocolError("claim_id is required for progress")
payload = {"claim_id": claim_id, "progress": progress, "stage": stage, "message": message, "lease_seconds": lease_seconds or self.config.default_lease_seconds}
return self._post(f"/tasks/{_safe_identifier(task_id, 'task_id')}/progress", payload)
def result(self, task_id: str, *, claim_id: str, status: str, outputs: list[dict[str, Any]], evidence: list[dict[str, Any]], started_at: str, completed_at: str, result_digest: str | None = None, operation_digest: str | None = None, trust_level: str | None = None, production_trust: bool | None = None, **_: Any) -> dict[str, Any]:
if not claim_id:
raise TaskClientProtocolError("claim_id is required for result submission")
if production_trust not in {None, False}:
raise TaskClientProtocolError("production_trust is forbidden")
payload = {"claim_id": claim_id, "status": status, "outputs": outputs, "evidence": evidence, "started_at": started_at, "completed_at": completed_at}
if result_digest:
payload["result_digest"] = result_digest
if operation_digest:
payload["operation_digest"] = operation_digest
if trust_level:
payload["trust_level"] = trust_level
payload["production_trust"] = False
return self._post(f"/tasks/{_safe_identifier(task_id, 'task_id')}/result", payload)
def evidence(self, task_id: str, *, claim_id: str, evidence: list[dict[str, Any]], status: str = "VERIFYING", started_at: str, completed_at: str) -> dict[str, Any]:
return self.result(task_id, claim_id=claim_id, status=status, outputs=[], evidence=evidence, started_at=started_at, completed_at=completed_at)
def fail(self, task_id: str, *, claim_id: str, reason: str = "failed", recoverable: bool = False) -> dict[str, Any]:
if not claim_id:
raise TaskClientProtocolError("claim_id is required for fail")
return self._post(f"/tasks/{_safe_identifier(task_id, 'task_id')}/fail", {"claim_id": claim_id, "reason": reason, "recoverable": recoverable})
@dataclass(frozen=True)
class WorkerConfig:
worker_id: str
worker_type: str
identity: str
trust_zone: str
max_concurrency: int = 1
heartbeat_interval_seconds: int = 15
claim_lease_seconds: int = 120
supported_protocols: tuple[str, ...] = ("aios-task-v1",)
capabilities: tuple[str, ...] = ("code.read", "test.python", "review.security")
def to_registration_payload(self) -> dict[str, Any]:
return {
"worker_id": self.worker_id, "worker_type": self.worker_type,
"identity": self.identity, "capabilities": list(self.capabilities),
"trust_zone": self.trust_zone, "max_concurrency": self.max_concurrency,
"heartbeat_interval_seconds": self.heartbeat_interval_seconds,
"supported_protocols": list(self.supported_protocols),
"owner_identity": self.identity, "registration_policy": "self",
}
@@ -1,162 +0,0 @@
"""Private, symlink-safe per-claim workspaces."""
from __future__ import annotations
import os
import shutil
import stat
from dataclasses import dataclass
from pathlib import Path
from .command_policy import isolated_environment
WORKSPACE_DIR_MODE = 0o700
RESULT_FILE_MODE = 0o600
class WorkspaceError(RuntimeError):
pass
class WorkspacePermissionError(WorkspaceError):
pass
class WorkspaceCleanupError(WorkspaceError):
pass
def _lexical(path: Path) -> Path:
return Path(os.path.abspath(os.fspath(path)))
def assert_private_path(path: Path, *, expected_mode: int = WORKSPACE_DIR_MODE) -> Path:
"""Reject every existing symlink before resolving the final path."""
lexical = _lexical(Path(path))
current = Path(lexical.anchor)
for component in lexical.parts[1:]:
current = current / component
try:
info = current.lstat()
except FileNotFoundError:
continue
if stat.S_ISLNK(info.st_mode):
raise WorkspacePermissionError("symlink path is forbidden")
return lexical
def _ensure_directory(path: Path, *, mode: int = WORKSPACE_DIR_MODE) -> None:
lexical = assert_private_path(path)
lexical.mkdir(mode=mode, parents=True, exist_ok=True)
if lexical.is_symlink() or not lexical.is_dir():
raise WorkspacePermissionError("workspace directory rejected")
os.chmod(lexical, mode)
if stat.S_IMODE(lexical.stat().st_mode) != mode:
raise WorkspacePermissionError("workspace directory mode rejected")
def _ensure_result_name(name: str) -> str:
safe = str(name).strip()
if not safe or safe in {".", ".."} or "/" in safe or "\\" in safe or "\0" in safe:
raise WorkspaceError("invalid result file name")
return safe
def _within(path: Path, base: Path) -> Path:
lexical = assert_private_path(path)
root = assert_private_path(base)
try:
lexical.relative_to(root)
except ValueError:
raise WorkspacePermissionError("path escapes workspace") from None
return lexical
def _copy_readonly_tree(source: Path, destination: Path) -> None:
source = assert_private_path(source)
if not source.is_dir():
raise WorkspaceError("source archive tree unavailable")
for item in source.rglob("*"):
if item.is_symlink():
raise WorkspacePermissionError("source archive symlink rejected")
shutil.copytree(source, destination, dirs_exist_ok=True, symlinks=False)
for item in destination.rglob("*"):
if item.is_file():
os.chmod(item, 0o400)
elif item.is_dir():
os.chmod(item, 0o500)
@dataclass(frozen=True)
class WorkspaceLayout:
workspace_root: Path
repo_root: Path
result_root: Path
home: Path
tmp: Path
@dataclass
class TaskWorkspace:
layout: WorkspaceLayout
task_id: str
claim_id: str
def __init__(self, root: Path, task_id: str, claim_id: str, *, repo_subdir: str = "repo") -> None:
workspace_root = assert_private_path(root)
_ensure_directory(workspace_root)
self.layout = WorkspaceLayout(
workspace_root, workspace_root / repo_subdir, workspace_root / "results",
workspace_root / "home", workspace_root / "tmp",
)
for path in (self.layout.repo_root, self.layout.result_root, self.layout.home, self.layout.tmp):
_ensure_directory(path)
self.task_id, self.claim_id = task_id, claim_id
@classmethod
def create(cls, root: Path, task_id: str, claim_id: str, *, repo_subdir: str = "repo") -> "TaskWorkspace":
return cls(root, task_id, claim_id, repo_subdir=repo_subdir)
def __enter__(self) -> "TaskWorkspace":
return self
def __exit__(self, *_: object) -> None:
self.cleanup()
def materialize_readonly_archive(self, source: Path) -> None:
if any(self.layout.repo_root.iterdir()):
raise WorkspaceError("workspace repository is not empty")
_copy_readonly_tree(source, self.layout.repo_root)
def environ(self) -> dict[str, str]:
return isolated_environment(self.layout.home, self.layout.tmp, "active-runtime")
def result_path(self, name: str) -> Path:
return _within(self.layout.result_root / _ensure_result_name(name), self.layout.result_root)
def write_result(self, *, name: str, payload: str) -> Path:
path = self.result_path(name)
flags = os.O_CREAT | os.O_WRONLY | os.O_TRUNC
if hasattr(os, "O_NOFOLLOW"):
flags |= os.O_NOFOLLOW
fd = os.open(path, flags, RESULT_FILE_MODE)
try:
if not stat.S_ISREG(os.fstat(fd).st_mode):
raise WorkspacePermissionError("result path is not regular")
os.write(fd, payload.encode("utf-8"))
os.fsync(fd)
os.fchmod(fd, RESULT_FILE_MODE)
finally:
os.close(fd)
return path
def cleanup(self) -> None:
root = assert_private_path(self.layout.workspace_root)
if not root.exists():
return
try:
shutil.rmtree(root)
except OSError as exc:
raise WorkspaceCleanupError("workspace cleanup failed") from exc
Workspace = TaskWorkspace
@@ -0,0 +1,83 @@
{
"approval_request_branch": "governance/request/integration-refresh-control-plane-deployment-20260728T093428Z",
"approval_type": "CONTROL_PLANE_DEPLOYMENT_APPROVAL_REQUEST",
"authorization_lineage": {
"execution_renewal_merge_oid": "3a22c3c7d86930efd4bd93ac05d80ad322050cb9",
"grant_id": "grant-11354281aafdd074df5899a3925dd2a0370cffa9edb06f5c7d7227ce8de00d91",
"source_mapping_approval_merge_oid": "9514062cf33e45941abe4a8c98377e0713b0b3f6"
},
"deployment_status": "NOT_EXECUTED",
"evidence": {
"control_plane_artifact": {
"path": "/var/lib/aios-integration-refresh-source-writer-v2/artifacts/control-plane-patch-112d995545e3e79126a062b2643a9f0c17ae7bd4.tar",
"sha256": "bf101ade1aaf956f40c0bba74ed4b347f5f38d0de6a0c1b7694ae107c4b43c14",
"size_bytes": 13363200
},
"rendered_systemd_config_sha256": "182a3cba48e752798cf24323a8c0249c53d7386371388a8db0435a29c43dc969",
"rollback_artifact": {
"path": "/var/lib/aios-gitops/runtime/tasks/AIOS-INTEGRATION-REFRESH-PROVISIONER-IMPLEMENTATION-20260726/implementation/rollback-to-85426f4f570e4d40b212318d47e52e4aed5cb06a.tar",
"sha256": "f12a2a95e475da5d02eaff99e93615cb0186019ca30edae013ab054a2c6418ce"
},
"source_map": {
"path": "docs/autonomous-release/INTEGRATION_REFRESH_SOURCE_MAP_20260728.json",
"sha256": "01ddd56cfa2a525559e2d174cf7df117a9465ffce44ef25bc7a15b8e74d06bf5"
},
"test_evidence": {
"collection_errors": 0,
"path": "/var/lib/aios-gitops/runtime/tasks/AIOS-INTEGRATION-REFRESH-PROVISIONER-IMPLEMENTATION-20260726/implementation/test-evidence.json",
"sha256": "d8933553f56462a3f1b3040dec989ff0adf717a17728d55ba0fe9e127d93c206",
"tests_failed": 0,
"tests_passed": 41
}
},
"execution_conditions": {
"candidate_only": true,
"integration_unchanged": true,
"main_unchanged": true,
"no_credentials_or_secrets_in_request": true,
"production_baseline_unchanged": true,
"registry_unchanged": true
},
"expected_governance_base_oid": "3a22c3c7d86930efd4bd93ac05d80ad322050cb9",
"expires_at": "2026-07-28T21:34:28Z",
"implementation": {
"commit_oid": "112d995545e3e79126a062b2643a9f0c17ae7bd4",
"tree_oid": "4ed88399fb8e7e4c235413ebbd783c9b6ad3c624"
},
"implementation_branch": "patch/integration-refresh-grant-provisioner-20260726",
"issued_at": "2026-07-28T09:34:28Z",
"prohibited_operations": [
"production-baseline.write",
"production-tag.write",
"main.write",
"integration.write",
"registry.write",
"force-push",
"direct-main-push",
"direct-tag-write"
],
"repository": "aios/aios",
"request_status": "PENDING_HUMAN_APPROVAL",
"requested_operations": [
"control-plane.candidate.deploy",
"control-plane.candidate.verify",
"control-plane.candidate.rollback"
],
"required_controls": [
"Two distinct human approvals, one Codex and one GPT, both APPROVED against the same current approval-request PR head.",
"Re-verify artifact, test evidence, source map, rendered systemd configuration, and rollback artifact paths and SHA-256 digests immediately before execution.",
"AIOS_GITOPS_WRITES_ENABLED=false throughout candidate deployment, verification, and rollback.",
"No force push, direct main write, or direct tag write."
],
"required_reviewers": [
"codex",
"gpt"
],
"schema": "aios.control-plane-deployment-approval-request/v1",
"target_governance": {
"approved_base_oid": "3a22c3c7d86930efd4bd93ac05d80ad322050cb9",
"binding_rule": "Human approvals must bind to the same approval-request PR head; its first parent must equal the active governance base."
},
"task_id": "AIOS-INTEGRATION-REFRESH-PROVISIONER-IMPLEMENTATION-20260726",
"validity_hours": 12
}
@@ -0,0 +1,127 @@
{
"schema": "aios.governance-approval/v1",
"approval_type": "TASK_SCOPED_GOVERNANCE_BOOTSTRAP_POLICY_ACTIVATION",
"approval_plan_id": "AIOS-TSG-BS-PHASE-A-RENEWAL-20260731T081147Z",
"task_id": "AIOS-V2R1C4-TWO-STAGE-OWNER-CAMPAIGN-V2-PHASE-A-RENEWAL",
"repository": "aios/aios",
"issued_at": "2026-07-31T08:11:47Z",
"expires_at": "2026-07-31T20:11:47Z",
"expected_governance_base_oid": "ebd74398743e36523b593fcc395b73945d4924c5",
"expected_governance_base_tree_oid": "ad1255a1127204fad1d1208d8f31dc94fa64e6e1",
"approval_request_branch": "governance/request/two-stage-owner-campaign-v2-phase-a-renewal-20260731T081147Z",
"request_head_binding": "GITEA_EXACT_HEAD_REVIEW_POST_COMMIT",
"human_authorizer": "owner",
"authorization_mode": "GITEA_EXACT_HEAD_REVIEW",
"required_human_approvals": 1,
"allowed_human_approvers": [
"owner"
],
"require_latest_head_approval": true,
"dismiss_stale_approvals": true,
"auto_merge_after_machine_gates": true,
"phase_a_scope": {
"schema_id": "TASK_SCOPED_GOVERNANCE_BOOTSTRAP",
"schema_version": 1,
"activate_schema_and_validator_only": true,
"phase_b_release_authorized": false,
"publisher_authorized": false,
"writer_authorized": false,
"credential_projection_authorized": false,
"tag_authorized": false,
"registry_authorized": false,
"baseline_authorized": false,
"production_deployment_authorized": false
},
"content_bindings": {
"schema_document": {
"path": "services/aios-single-owner-governance/task-scoped-governance-bootstrap-v1.schema.json",
"blob_oid": "9b117667c0d98f995ac059b0e1b5ffed06ca6444",
"sha256": "6ec912a96c8bac5c0d3c0a017abc078cb9567ed54dcb20bb0eadb5926ac54fdd"
},
"validator_policy": {
"path": "services/aios-single-owner-governance/aios_single_owner_governance/task_scoped_bootstrap.py",
"blob_oid": "c18d15f31340f19fc5da87944901bdfb867ab6dc",
"sha256": "de11123b5cd9ccdad4961f1d5d084a8c4a1b2270ce793652ab9c50bb95694eac"
},
"evidence_manifest": {
"path": "evidence/governance-policy/AIOS-TWO-STAGE-OWNER-CAMPAIGN-V2-PHASE-A-20260730T023551Z.json",
"blob_oid": "c3d215b3ea525a25de514c32c5aad91d47e140b4",
"sha256": "1b0a993940b41a4b16724b557f6abd8b6cebb56dc64cc8f813bd605b6a3399c2"
},
"checksums_manifest": {
"path": "evidence/governance-policy/AIOS-TWO-STAGE-OWNER-CAMPAIGN-V2-PHASE-A-20260730T023551Z.sha256",
"blob_oid": "45ed084234dae6a00e69a41cd4f716f46a97d9fb",
"sha256": "51c4b029c0792dc98d41f754e484ba3861cf7604443d9c5f289b3b0af768a41a"
}
},
"offline_candidate_bindings": {
"schema_seed_commit_oid": "8da47545a507cb798d3d6ab30ff8552a2d0a5ecf",
"schema_seed_tree_oid": "991e68577a469657c1c4996814b6634ce5ed752f",
"implementation_commit_oid": "a637a9dbb6e0021cb7dcf0d6b0ca00dfe10dce38",
"implementation_tree_oid": "bf6e0c16fcad7515465bec4aefdd2e77b1e9bef0",
"evidence_closure_commit_oid": "1e4885197f508f7921b148d71e545b3de0029b0a",
"evidence_closure_tree_oid": "e55cf9ef19d1c6804f161de54fd3395a06149807",
"source_diff_sha256": "c06d002db06da6cbf16f9c8321f1acbfd431f009b5127a13fd2cb5d63b278867",
"source_pathset_sha256": "5061402d516c0e9413208ce64e2b52f77d224e6eec1f7b07c5b3a10b58df5eaf",
"implementation_bundle_sha256": "15711b225b9ef41cca0588d21b2b95d7a95ac155efc27fcb8772c435fcdab147",
"evidence_bundle_sha256": "ec97b8460151fc0e7e7ea9ae044ca13a1543c4b79c41a437ef087d3b1c271857"
},
"runtime_dependency_bindings": {
"handoff_zip_sha256": "668239a549b4a2b2094fe9b5104b84703fe8ed75011fd8ed71ed3958a6dc0706",
"installed_wheel_sha256": "abbf616366eb3467d4e651bb5306e22ae5e931b613df5362a0892935c4a1c0c7",
"anchor_service": "aios-campaign-anchor.service",
"anchor_uid": 988,
"runner_uid": 986,
"anchor_database": "/var/lib/aios-campaign-anchor/anchor.sqlite3",
"anchor_socket": "/run/aios-campaign-anchor/anchor.sock",
"AIOS_GITOPS_WRITES_ENABLED": false
},
"required_machine_status_contexts": [
"governance/schema-contract",
"governance/validator-security",
"governance/fault-injection",
"governance/runtime-isolation",
"governance/authority-mirror"
],
"allowed_operations_after_exact_head_owner_approval": [
"observe_governance_pr",
"wait_governance_gates",
"observe_governance_merge",
"observe_validator_activation",
"complete_policy_activation"
],
"denied_operations": [
"main.write",
"integration.write",
"tag.write",
"registry.write",
"baseline.write",
"production.deploy",
"force_push",
"history_rewrite",
"governance.direct_push",
"approval.impersonate",
"publisher.create",
"writer.create",
"credential.project",
"phase_b.execute"
],
"merge_constraints": {
"allowed_modes": [
"FAST_FORWARD_TO_APPROVED_HEAD",
"EXACT_TWO_PARENT_MERGE_WITH_APPROVED_TREE"
],
"force": false,
"plus_refspec": false,
"tags": false,
"prune": false
},
"governance_declarations": {
"AIOS_GITOPS_WRITES_ENABLED": false,
"force_push_used": false,
"tag_rewritten": false,
"direct_main_push": false,
"secrets_committed": false,
"owner_approval_respected": true
}
}
@@ -0,0 +1,113 @@
{
"approval_type": "TASK_STATUS_MERGE_BROKER_BOOTSTRAP",
"schema_version": 1,
"repository": "aios/aios",
"expected_governance_base_oid": "8814dff20222625b60454c613b61ccf15fa20e51",
"request_branch": "governance/bootstrap/task-status-merge-broker-20260801t0036z",
"issued_at": "2026-08-01T00:46:50Z",
"expires_at": "2026-08-01T12:46:50Z",
"required_human_approvals": 1,
"allowed_human_approvers": ["owner"],
"require_latest_head_approval": true,
"purpose": "Activate a task-scoped credential, status, and fast-forward-only merge broker so a new V2R1C4 Phase B renewal can satisfy existing branch protection without impersonation or long-lived credentials.",
"phase_b_transition": {
"old_pr_number": 36,
"old_head_oid": "a8644fc172bd8ebbba17a16e6bf586c93fd1e793",
"reuse_after_governance_base_change": false,
"renewal_required_after_bootstrap_merge": true
},
"allowed_status_contexts": [
"aios/branch-protection",
"aios/evidence-closure",
"aios/secret-scan",
"aios/state-machine",
"aios/validator"
],
"allowed_identities": ["codex", "gpt"],
"allowed_operations": [
"issue_task_status_credential",
"issue_task_merge_credential",
"sign_task_grant_after_owner_exact_head_review",
"publish_exact_five_statuses",
"fast_forward_only_merge",
"readback_status_and_ref",
"revoke_task_credentials",
"remove_credential_projection"
,"sweep_completed_or_expired_task_credentials"
],
"operation_limits": {
"maximum_status_writes_per_grant": 5,
"maximum_merges_per_grant": 1,
"maximum_grant_lifetime_seconds": 43200,
"automatic_revocation_required": true
},
"denied_operations": [
"branch_push",
"main_push",
"tag_write",
"registry_write",
"baseline_write",
"production_write",
"branch_protection_change",
"force_push",
"squash",
"rebase",
"merge_commit",
"approval_impersonation",
"plaintext_secret_persistence"
,"sign_unapproved_grant"
,"reuse_superseded_pr"
,"grant_signing_private_key_projection_to_broker"
,"commit_status_database_write"
,"database_write_outside_exact_access_token_revocation"
],
"runtime_controls": {
"global_gitops_writes_enabled": false,
"runtime_secret_only": true,
"systemd_encrypted_credentials_required": true,
"token_in_argv_allowed": false,
"token_in_log_allowed": false,
"separate_non_root_status_identity": true,
"separate_non_root_merge_identity": true,
"root_credential_broker_only": true,
"sqlite_quota_and_hash_chain_audit": true,
"hmac_audit_signature": true,
"detached_ssh_grant_signature_required": true,
"broker_receives_public_verification_key_only": true,
"grant_signing_requires_live_owner_exact_head_review": true,
"grant_signing_requires_open_pr_exact_head_base_tree_manifest": true,
"status_evidence_digest_bound_in_signed_grant": true,
"credential_issue_rechecks_local_pr_review_ref_tree_manifest": true,
"gitea_write_repository_scope_compensated_by_locked_broker_sandbox": true,
"token_revocation_exact_row_and_http_401_required": true,
"gitea_1_22_token_delete_requires_basic_auth": true,
"exact_access_token_row_revocation_exception": true,
"access_token_revocation_binding_fields": ["id", "uid", "name", "scope"],
"commit_status_database_write_allowed": false,
"credential_completion_and_expiry_sweep_interval_seconds": 60,
"sweeper_uses_same_per_task_audit_credential_as_issuer": true,
"gitea_api_origin": "http://127.0.0.1:3000/api/v1",
"merge_method": "fast-forward-only"
},
"approved_files": {
"services/aios-single-owner-governance/aios_single_owner_governance/task_status_merge_broker.py": "79a7b6807dc9e6c167c94adbd3bb4a1b9ae17e54d2d6fd19bd6a38ce2f8b8e3f",
"services/aios-single-owner-governance/aios_single_owner_governance/task_credential_broker.py": "678fccd8e61fa1806d44fbb81fe7f6e2a7b63bbd99d1323516073100b6e48ab5",
"services/aios-single-owner-governance/aios_single_owner_governance/task_credential_expiry_sweeper.py": "8d383768eb0322c84a35282c126bee26a3e6419b125780424ffc7793a504efdf",
"services/aios-single-owner-governance/task-status-merge-grant-v1.schema.json": "4528aa6dfeaa151deadb54bf1c462e1ff3e9526e0da3eb20144e6c01c19998f0",
"tests/single_owner_governance/test_task_status_merge_broker.py": "65a285b29798b72d13e30562ce97529780643f3739e5d07c283dfa5995035dc4",
"deploy/systemd/aios-task-status-broker@.service": "378a2e8f658cb56cac5dcc151772ec6a00d86f6c1ce3106509b9aa87549dc9da",
"deploy/systemd/aios-task-merge-broker@.service": "4e6b8fcf541f225e58ea080107fc30deb0c4ac9eac70217ff9e57081245c106a",
"deploy/systemd/aios-task-credential-broker@.service": "ec5dd2be87f3e02af89a40a615ccbd76a277f46aa29cc1a92fee5496d750cbce",
"deploy/systemd/aios-task-credential-expiry-sweeper.service": "39726537a3b4f57614eba678309fd3009c8fa25448458827aef7ece0015be10d",
"deploy/systemd/aios-task-credential-expiry-sweeper.timer": "49ff9c80cbd0b44fd584dc7d29f4db0d042e33f325b1ed7af81a5be42f1cd011"
},
"machine_gate_requirements": {
"compileall": "PASS",
"unit_tests": "PASS",
"json_schema": "PASS",
"systemd_validation": "PASS",
"secret_scan": "PASS",
"fault_injection": "PASS",
"scope_boundary_tests": "PASS"
}
}
@@ -0,0 +1,79 @@
{
"AIOS_GITOPS_WRITES_ENABLED": false,
"acknowledges_pr30_owner_approval_was_missing": true,
"activation_prerequisites_artifact_sha256": "729077800c6510bf8930c97a78781218d1bce9ec40157aa99fc2bd205466e895",
"activation_prerequisites_commit_oid": "fa038d17b29001e26f1ac88019a407a4b3ebaa7e",
"activation_prerequisites_rollback_artifact_sha256": "00e40eace10a0aae1731eb98851fec71a0c13c48e1e6e5a113e30a4356c2086f",
"activation_prerequisites_tree_oid": "d5ff67f848807ef2c7a695c05cdd0bb5f2644fc2",
"approval_request_branch": "governance/request/single-owner-atomic-activation-owner-ratification-20260729T014918Z-e503d96665ee",
"approval_type": "SINGLE_OWNER_GOVERNANCE_ATOMIC_ACTIVATION_OWNER_RATIFICATION",
"branch_protection_adapter_sha256": "2706dc6095ff639838f72c91a66c1f80711893c8c0498555b388feaacf2db569",
"denied_operations": [
"main.write",
"integration.write",
"tag.write",
"registry.write",
"baseline.write",
"production.deploy",
"force_push",
"history_rewrite",
"governance.direct_push",
"approval.impersonate"
],
"direct_protected_branch_push_allowed": false,
"dismiss_stale_approvals": true,
"dormant_deployment_evidence_sha256": "c4c326784a3d66d62e32c46be3506c801585c06a34e62c9a1f210492a6c1bc06",
"evidence_closure_oid": "5f45139ca5f7f7f3da244141c5115d12f5af58ae",
"evidence_closure_sha256": "53e5f2fdc01a6225048dfdf6eac973e99743f0295f17f3a42f01dce7e7050ab8",
"expected_governance_base_oid": "f6bef90633f428454e85721f353cd82cdf04caf0",
"expires_at": "2026-07-29T13:49:18Z",
"explicitly_allowed_operations_after_exact_head_approvals_and_merge": [
"approval_validator.activate",
"governance_state_machine.activate",
"gitea_branch_protection.atomic_update",
"rollback_configuration.install",
"single_owner_policy.activate",
"break_glass.expire",
"post_activation_tests.execute"
],
"force_push_allowed": false,
"human_authorizer": "owner",
"issued_at": "2026-07-29T01:49:18Z",
"legacy_mechanical_approvals": [
"codex",
"gpt"
],
"merge_mode": "CREATE_MERGE_COMMIT",
"pr30_codex_approval_review_id": 45,
"pr30_codex_reviewed_at": "2026-07-29T01:24:38Z",
"pr30_codex_reviewed_head_oid": "c2eed5b37983a6461783361efb6de43a28f909bb",
"pr30_gpt_approval_review_id": 46,
"pr30_gpt_reviewed_at": "2026-07-29T01:25:02Z",
"pr30_gpt_reviewed_head_oid": "c2eed5b37983a6461783361efb6de43a28f909bb",
"pr30_manifest_path": "approvals/governance-policy/SINGLE-OWNER-GOVERNANCE-ATOMIC-ACTIVATION-20260728T204808Z-4cab1d5829d6.json",
"pr30_merge_tree_oid": "219974f085efe473fcc6ad2170f67312d8e57c54",
"pr30_merged_at": "2026-07-29T01:25:08Z",
"pr30_owner_review_id": 42,
"pr30_owner_review_state_observed": "REQUESTED_NOT_APPROVED",
"pr30_owner_reviewed_head_oid": null,
"pr30_premerge_base_oid": "6e8212608ee310e2fb45f1e802359f4db2e9077b",
"production_deployment_allowed": false,
"ratifies_pr30_manifest_blob_oid": "38c95dde2d3831f8e3c80b342369f1c3e1cbf34c",
"ratifies_pr30_manifest_sha256": "bc19ada0e8eeb47d421a6360cf1d66b6d1129eb6056a447d9ff70ebd5ada1718",
"ratifies_pr30_merge_oid": "f6bef90633f428454e85721f353cd82cdf04caf0",
"ratifies_pr30_request_oid": "c2eed5b37983a6461783361efb6de43a28f909bb",
"ratifies_pr_number": 30,
"require_latest_head_approval": true,
"required_reviewers": [
"owner",
"codex",
"gpt"
],
"rollback_configuration_sha256": "eb44fc5f655f8c30c4b687185055ba3a2725189e19538e3a9a46a2c0cf141b8c",
"schema": "aios.governance-approval/v1",
"state_machine_sha256": "0b08a2c378d143cb9031a25132afc7b7d825bdc03d11efe10610341d4b70167e",
"task_id": "AIOS-PR30-SINGLE-OWNER-ATOMIC-ACTIVATION-OWNER-RATIFICATION-20260729",
"test_evidence_sha256": "42168da7437028440bece3432d8aa38a8722b4db18244423d9daaa380675c45a",
"validator_sha256": "754639846cb15cb997d612a1fe0ceb0224ddef5bbc3ccac9802a3747f122dac1",
"wip_blocks_merge": true
}
@@ -0,0 +1,91 @@
{
"approval_request_branch": "governance/request/single-owner-governance-activation-prerequisites-20260728T183025127107Z",
"approval_type": "SINGLE_OWNER_GOVERNANCE_ACTIVATION_PREREQUISITES",
"binds_final_ratification_manifest_blob_oid": "2865fbec766901eb61fc8aed0542970e951e0d1d",
"binds_final_ratification_manifest_sha256": "216e54503d8e6a3f4c908084e19ce1e6242d3ba15f7b8011a9a9d9f7975e63e7",
"binds_final_ratification_merge_oid": "2bef44f6bc8cf7bc04c959ab629ac95561fa609f",
"binds_mirror_receipt_sha256": "6873133f7233bfed0d3b78b01847ad4251b8b67f3b6db7011efd07664f8d088f",
"expected_governance_base_oid": "2bef44f6bc8cf7bc04c959ab629ac95561fa609f",
"expires_at": "2026-07-29T06:30:25Z",
"explicitly_allowed_after_owner_approval_and_legacy_merge": [
"task_bound_activation_writer_grant.create",
"gitea_owner_review_adapter.create_and_dormant_deploy",
"machine_status_producer.create_and_dormant_deploy",
"machine_status_producer.credential_rotation_and_revocation",
"maintenance_lock.create",
"branch_protection_compensation_saga.create",
"targeted_online_rollback_executor.create",
"disposable_gitea_fixture.create_test_destroy",
"single_owner_activation_prerequisite_tests.execute",
"activation_prerequisite_evidence.create"
],
"implementation_branch": "patch/single-owner-governance-activation-prerequisites-20260729",
"implementation_paths": [
"services/aios-single-owner-governance/**",
"tests/single_owner_governance/**",
"deploy/systemd/aios-governance-*.service",
"deploy/systemd/aios-governance-*.timer"
],
"issued_at": "2026-07-28T18:30:25Z",
"machine_status_contexts": [
"aios/machine-gates",
"aios/secret-scan",
"aios/evidence-closure"
],
"observed_blockers": {
"commit_status_row_count": 0,
"disposable_governance_fixture_present": false,
"gitea_owner_review_validator_present": false,
"gitea_version": "1.22.6",
"native_branch_protection_etag_cas_present": false,
"required_status_context_producers_present": false,
"targeted_online_rollback_executor_present": false
},
"owner_approval_contract": {
"agent_must_not_submit_review": true,
"dismissed": false,
"head_change_invalidates_approval": true,
"only_human_approver": "owner",
"owner_user_id": 2,
"review_state": "APPROVED",
"reviewed_before_expires_at": true,
"reviewed_head_oid_must_equal_current_head_oid": true,
"stale": false
},
"permanent_constraints": {
"AIOS_GITOPS_WRITES_ENABLED": false,
"direct_main_push": false,
"force_push": false,
"history_rewrite": false,
"secret_commit": false,
"tag_rewrite": false
},
"pre_approval_non_authorizations": {
"activation_allowed": false,
"baseline_write_allowed": false,
"branch_protection_change_allowed": false,
"fixture_deployment_allowed": false,
"integration_write_allowed": false,
"main_write_allowed": false,
"merge_allowed": false,
"production_write_allowed": false,
"registry_write_allowed": false,
"tag_write_allowed": false,
"writer_grant_allowed": false
},
"reason": "safe-atomic-activation-prerequisites-absent",
"repository": "aios/aios",
"request_status": "HUMAN_OWNER_APPROVAL_PENDING",
"schema": "aios.single-owner-governance-activation-prerequisites/v1",
"task_id": "AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-PREREQUISITES-20260729",
"wip": true,
"wip_transition_contract": {
"codex_and_gpt_not_requested_before_owner_approval": true,
"remove_wip_without_head_change_only_after_owner_approval": true,
"then_request_legacy_mechanical_reviews": [
"codex",
"gpt"
],
"wip_must_remain_until_owner_exact_head_approval": true
}
}
@@ -0,0 +1,68 @@
{
"AIOS_GITOPS_WRITES_ENABLED": false,
"activation_prerequisites_artifact_sha256": "729077800c6510bf8930c97a78781218d1bce9ec40157aa99fc2bd205466e895",
"activation_prerequisites_commit_oid": "fa038d17b29001e26f1ac88019a407a4b3ebaa7e",
"activation_prerequisites_rollback_artifact_sha256": "00e40eace10a0aae1731eb98851fec71a0c13c48e1e6e5a113e30a4356c2086f",
"activation_prerequisites_tree_oid": "d5ff67f848807ef2c7a695c05cdd0bb5f2644fc2",
"approval_request_branch": "governance/request/single-owner-governance-atomic-activation-20260728T204808Z-4cab1d5829d6",
"approval_type": "SINGLE_OWNER_GOVERNANCE_ATOMIC_ACTIVATION",
"branch_protection_adapter_sha256": "2706dc6095ff639838f72c91a66c1f80711893c8c0498555b388feaacf2db569",
"denied_operations": [
"main.write",
"integration.write",
"tag.write",
"registry.write",
"baseline.write",
"production.deploy",
"force_push",
"history_rewrite",
"governance.direct_push",
"approval.impersonate"
],
"deployment_mode_before_execution": "DORMANT_SHADOW_ONLY",
"direct_protected_branch_push_allowed": false,
"dismiss_stale_approvals": true,
"dormant_deployment_evidence_sha256": "c4c326784a3d66d62e32c46be3506c801585c06a34e62c9a1f210492a6c1bc06",
"evidence_closure_oid": "5f45139ca5f7f7f3da244141c5115d12f5af58ae",
"evidence_closure_sha256": "53e5f2fdc01a6225048dfdf6eac973e99743f0295f17f3a42f01dce7e7050ab8",
"expected_governance_base_oid": "6e8212608ee310e2fb45f1e802359f4db2e9077b",
"expires_at": "2026-07-29T08:48:08Z",
"explicitly_allowed_operations_after_exact_head_approvals_and_merge": [
"approval_validator.activate",
"governance_state_machine.activate",
"gitea_branch_protection.atomic_update",
"rollback_configuration.install",
"single_owner_policy.activate",
"break_glass.expire",
"post_activation_tests.execute"
],
"force_push_allowed": false,
"issued_at": "2026-07-28T20:48:08Z",
"legacy_mechanical_approvals": [
"codex",
"gpt"
],
"machine_gates_required": true,
"merge_mode": "CREATE_MERGE_COMMIT",
"pr26_merge_oid": "a5489f1b67870622162b2daa781bd0237735831a",
"pr27_merge_oid": "4e6ef70029b1d94626e432892f7d3beb8e3e5627",
"pr28_merge_oid": "2bef44f6bc8cf7bc04c959ab629ac95561fa609f",
"pr29_merge_oid": "6e8212608ee310e2fb45f1e802359f4db2e9077b",
"production_deployment_allowed": false,
"require_latest_head_approval": true,
"required_human_authorizer": "owner",
"required_reviewers": [
"owner",
"codex",
"gpt"
],
"rollback_configuration_sha256": "eb44fc5f655f8c30c4b687185055ba3a2725189e19538e3a9a46a2c0cf141b8c",
"rollback_required_on_any_activation_failure": true,
"schema": "aios.governance-approval/v1",
"single_owner_policy_active_before_execution": false,
"state_machine_sha256": "0b08a2c378d143cb9031a25132afc7b7d825bdc03d11efe10610341d4b70167e",
"task_id": "AIOS-SINGLE-OWNER-GOVERNANCE-ATOMIC-ACTIVATION-20260729",
"test_evidence_sha256": "42168da7437028440bece3432d8aa38a8722b4db18244423d9daaa380675c45a",
"validator_sha256": "754639846cb15cb997d612a1fe0ceb0224ddef5bbc3ccac9802a3747f122dac1",
"wip_blocks_merge": true
}
@@ -0,0 +1,268 @@
{
"acknowledges_pr26_owner_approval_was_missing": true,
"approval_request_branch": "governance/request/single-owner-control-plane-deployment-20260728T170740Z-ea7a102dac417c23",
"approval_type": "SINGLE_OWNER_GOVERNANCE_CONTROL_PLANE_DEPLOYMENT",
"control_plane_targets": {
"allowed_human_approvers": [
"owner"
],
"branch_deletion": false,
"direct_protected_branch_push": false,
"dismiss_stale_approvals": true,
"executor_must_not_approve": true,
"force_push": false,
"governance_model": "SINGLE_OWNER_WITH_MACHINE_GATES_V1",
"historical_records_immutable": true,
"machine_gates_required": true,
"policy_effective_at_set_only_after_activation_tests_pass": true,
"protected_branches": [
"governance/approvals",
"main",
"release/**",
"integration/**"
],
"requester_must_not_approve": true,
"require_approval_for_latest_commit": true,
"required_human_approvals": 1,
"required_owner_approvals": 1,
"required_status_contexts": [
"aios/machine-gates",
"aios/secret-scan",
"aios/evidence-closure"
],
"tag_rewrite": false,
"wip_blocks_merge": true
},
"does_not_claim_pr26_met_old_two_natural_person_policy": true,
"expected_authoritative_governance_base_oid": "ac2dc5c30eb35748ef11c98297812729d0fd5828",
"expected_gitea_governance_base_oid": "a5489f1b67870622162b2daa781bd0237735831a",
"expires_at": "2026-07-29T05:07:40Z",
"explicitly_allowed_operations_after_exact_head_approvals_and_merge": [
"approval_mirror.fast_forward_governance_only",
"approval_validator.update",
"state_machine.update",
"gitea_branch_protection.update_via_authenticated_api_compare_and_swap",
"governance_policy.activate",
"rollback_configuration.install",
"governance_acceptance_tests.execute",
"single_owner_governance_activation_receipt.create"
],
"explicitly_denied_operations": [
"force_push",
"plus_refspec",
"tag_fetch",
"prune",
"direct_git_database_write",
"direct_protected_ref_push",
"main_write",
"integration_write",
"tag_write",
"registry_write",
"baseline_write",
"production_write",
"history_rewrite",
"branch_delete",
"secret_read",
"approval_impersonation"
],
"global_constraints": {
"AIOS_GITOPS_WRITES_ENABLED": false,
"direct_main_push": false,
"force_push_used": false,
"owner_approval_respected": true,
"secrets_committed": false,
"tag_rewritten": false
},
"implementation_surface": {
"approval_validator": [
"services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/approval.py",
"services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/models.py",
"services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/policy.py"
],
"runtime": [
"active-runtime/app/silent_release_controller.py",
"active-runtime/app/silent_release_hardening.py"
],
"state_machine": [
"services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/store.py",
"services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/workflow.py",
"services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/release.py"
],
"systemd": [
"deploy/systemd/aios-autonomous-release-candidate.service",
"deploy/systemd/aios-silent-release-controller.service"
]
},
"issued_at": "2026-07-28T17:07:40Z",
"legacy_gitea_protection_gate": {
"account_reviews_do_not_prove_distinct_natural_persons": true,
"both_must_approve_this_exact_head": true,
"current_approval_whitelist": [
"codex",
"gpt"
],
"current_required_approvals": 2
},
"migration_mode": "OWNER_BREAK_GLASS_GOVERNANCE_RESET_RATIFICATION",
"mirror_contract": {
"expected_chain_contains_policy_merge_oid": "a5489f1b67870622162b2daa781bd0237735831a",
"expected_pre_sync_authoritative_oid": "ac2dc5c30eb35748ef11c98297812729d0fd5828",
"fast_forward_only": true,
"force": false,
"fsck_connectivity_only_required": true,
"only_ref": "refs/heads/governance/approvals",
"plus_refspec": false,
"prune": false,
"quarantine_required": true,
"source": "gitea_repository_file_url_only",
"tags": false
},
"owner_break_glass_ratification": {
"attests_reason": "single-maintainer-system",
"attests_scope": "governance-policy-migration-only",
"created_before_expires_at": true,
"dismissed": false,
"required": true,
"review_state": "APPROVED",
"reviewed_head_oid_must_equal_current_pr_head_oid": true,
"reviewer_user_id": 2,
"reviewer_username": "owner",
"stale": false
},
"pre_approval_non_authorizations": {
"approval_validator_update_allowed": false,
"development_allowed": false,
"gitea_branch_protection_update_allowed": false,
"governance_policy_activation_allowed": false,
"merge_allowed": false,
"mirror_allowed": false,
"production_change_allowed": false,
"rollback_install_allowed": false,
"standing_writer_policy_allowed": false,
"state_machine_update_allowed": false
},
"pre_cutover_protection_snapshot": {
"protected_branch": [
{
"approvals_whitelist_team_i_ds": "null",
"approvals_whitelist_user_i_ds": "[42,43]",
"block_on_official_review_requests": 1,
"block_on_outdated_branch": 1,
"block_on_rejected_reviews": 1,
"branch_name": "governance/approvals",
"can_push": 0,
"created_unix": 1785093201,
"dismiss_stale_approvals": 1,
"enable_approvals_whitelist": 1,
"enable_merge_whitelist": 1,
"enable_status_check": 0,
"enable_whitelist": 0,
"id": 1,
"ignore_stale_approvals": 0,
"merge_whitelist_team_i_ds": "null",
"merge_whitelist_user_i_ds": "[42,43]",
"protected_file_patterns": "",
"repo_id": 1,
"require_signed_commits": 0,
"required_approvals": 2,
"status_check_contexts": "[]",
"unprotected_file_patterns": "",
"updated_unix": 1785093422,
"whitelist_deploy_keys": 0,
"whitelist_team_i_ds": "null",
"whitelist_user_i_ds": "null"
},
{
"approvals_whitelist_team_i_ds": "null",
"approvals_whitelist_user_i_ds": "[42,43]",
"block_on_official_review_requests": 1,
"block_on_outdated_branch": 1,
"block_on_rejected_reviews": 1,
"branch_name": "integration/chatgpt-autonomous-completion-20260726",
"can_push": 0,
"created_unix": 1785093201,
"dismiss_stale_approvals": 1,
"enable_approvals_whitelist": 1,
"enable_merge_whitelist": 1,
"enable_status_check": 0,
"enable_whitelist": 0,
"id": 3,
"ignore_stale_approvals": 0,
"merge_whitelist_team_i_ds": "null",
"merge_whitelist_user_i_ds": "[42,43]",
"protected_file_patterns": "",
"repo_id": 1,
"require_signed_commits": 0,
"required_approvals": 2,
"status_check_contexts": "[]",
"unprotected_file_patterns": "",
"updated_unix": 1785093422,
"whitelist_deploy_keys": 0,
"whitelist_team_i_ds": "null",
"whitelist_user_i_ds": "null"
},
{
"approvals_whitelist_team_i_ds": "null",
"approvals_whitelist_user_i_ds": "[42,43]",
"block_on_official_review_requests": 1,
"block_on_outdated_branch": 1,
"block_on_rejected_reviews": 1,
"branch_name": "main",
"can_push": 0,
"created_unix": 1785093201,
"dismiss_stale_approvals": 1,
"enable_approvals_whitelist": 1,
"enable_merge_whitelist": 1,
"enable_status_check": 0,
"enable_whitelist": 0,
"id": 2,
"ignore_stale_approvals": 0,
"merge_whitelist_team_i_ds": "null",
"merge_whitelist_user_i_ds": "[42,43]",
"protected_file_patterns": "",
"repo_id": 1,
"require_signed_commits": 0,
"required_approvals": 2,
"status_check_contexts": "[]",
"unprotected_file_patterns": "",
"updated_unix": 1785093422,
"whitelist_deploy_keys": 0,
"whitelist_team_i_ds": "null",
"whitelist_user_i_ds": "null"
}
],
"protected_tag": []
},
"pre_cutover_protection_snapshot_sha256": "2bc353f34689242cabebf89856d3faab0e1c496b5d33761dfb7cbd47904516f7",
"ratifies_policy_manifest_blob_oid": "65f44007b10fc2a912d69e3f9081c0cfff77dfad",
"ratifies_policy_manifest_path": "approvals/governance-policy/SINGLE-OWNER-GOVERNANCE-MIGRATION-20260728T162246Z.json",
"ratifies_policy_manifest_sha256": "c097475afbe3074e6482f125b635981f8c0284f3d763c926e2a63e1a3ee1c6c3",
"ratifies_policy_merge_oid": "a5489f1b67870622162b2daa781bd0237735831a",
"ratifies_policy_pr_number": 26,
"ratifies_policy_request_oid": "312d3b483049a748675e887a516ec739c81ff474",
"ratifies_policy_tree_oid": "5c6974c058bba6210dcc1bdd0968fb7e6c84a844",
"repository": "aios/aios",
"request_status": "HUMAN_OWNER_AND_LEGACY_PROTECTION_APPROVAL_PENDING",
"required_machine_gates": [
"owner_exact_head_review_valid",
"legacy_protection_reviews_valid",
"ordinary_merge_commit",
"parent_order_verified",
"manifest_add_only",
"quarantine_verification",
"approval_mirror_fast_forward",
"validator_tests",
"state_machine_tests",
"protection_compare_and_swap",
"positive_governance_tests",
"negative_governance_tests",
"secret_scan",
"rollback_integrity",
"production_write_false"
],
"rollback_configuration_path": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-MIGRATION-20260729/rollback-configuration.tar",
"rollback_configuration_sha256": "fc8dcf68aaf53edb0cda45833ee45ba5b8b205791af9073258ca617c8b8187d6",
"schema": "aios.single-owner-governance-control-plane-deployment/v1",
"scope": "pr26-ratification-mirror-and-single-owner-control-plane-deployment-only",
"task_id": "AIOS-SINGLE-OWNER-CONTROL-PLANE-DEPLOYMENT-20260729"
}
@@ -0,0 +1,260 @@
{
"acknowledges_pr26_and_pr27_owner_approval_was_missing": true,
"approval_request_branch": "governance/request/single-owner-governance-final-owner-ratification-20260728T173634412838Z",
"approval_type": "SINGLE_OWNER_GOVERNANCE_FINAL_OWNER_RATIFICATION",
"backup_checksums_sha256": "72e2fe0b03d1011c872bb39a6cff489f08398ac7d52092f720cbbc63bcf6f753",
"backup_root": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-MIGRATION-20260729/pre-migration-backup",
"break_glass_expires_immediately_after_activation": true,
"does_not_claim_old_two_natural_person_compliance": true,
"expires_at": "2026-07-29T05:36:34Z",
"inherits_only_pr27_control_plane_allowlist": [
"approval_mirror.fast_forward_governance_only",
"approval_validator.update",
"state_machine.update",
"gitea_branch_protection.update_via_authenticated_api_compare_and_swap",
"governance_policy.activate",
"rollback_configuration.install",
"governance_acceptance_tests.execute",
"single_owner_governance_activation_receipt.create"
],
"issued_at": "2026-07-28T17:36:34Z",
"legacy_mechanical_protection_gate": {
"account_reviews_do_not_count_as_owner_ratification": true,
"account_reviews_do_not_prove_distinct_natural_persons": true,
"approval_and_merge_whitelist_user_ids": [
42,
43
],
"both_reviews_must_bind_current_request_head": true,
"required_approvals": 2,
"reviewers": [
"codex",
"gpt"
]
},
"merge_contract": {
"first_parent_must_equal_premerge_governance_oid": true,
"force": false,
"merge_mode": "CREATE_MERGE_COMMIT",
"parent_count": 2,
"rebase": false,
"second_parent_must_equal_final_ratification_request_oid": true,
"single_file_add_only": true,
"squash": false
},
"migration_mode": "OWNER_BREAK_GLASS_GOVERNANCE_RESET",
"mirror_contract": {
"expected_authoritative_pre_oid": "ac2dc5c30eb35748ef11c98297812729d0fd5828",
"fast_forward_only": true,
"force": false,
"fsck_connectivity_only_required": true,
"only_ref": "refs/heads/governance/approvals",
"plus_refspec": false,
"prune": false,
"quarantine_required": true,
"required_chain": [
"ac2dc5c30eb35748ef11c98297812729d0fd5828",
"a5489f1b67870622162b2daa781bd0237735831a",
"4e6ef70029b1d94626e432892f7d3beb8e3e5627",
"FINAL_RATIFICATION_MERGE_OID"
],
"source": "gitea_repository_file_url_only",
"tags": false
},
"owner_ratification_contract": {
"agent_must_not_submit_review": true,
"dismissed": false,
"only_valid_human_approver": "owner",
"owner_user_id": 2,
"review_state": "APPROVED",
"review_type_must_be_approved_not_requested": true,
"reviewed_before_expires_at": true,
"reviewed_before_merge": true,
"reviewed_head_oid_must_equal_current_request_head_oid": true,
"stale": false
},
"permanent_constraints": {
"AIOS_GITOPS_WRITES_ENABLED": false,
"direct_main_push": false,
"force_push_used": false,
"owner_approval_respected": true,
"secrets_committed": false,
"tag_rewritten": false
},
"post_merge_activation_preconditions": [
"owner_exact_head_approval_valid",
"legacy_mechanical_reviews_valid",
"ordinary_merge_commit",
"one_file_add_only",
"quarantine_chain_verified",
"approval_mirror_fast_forward_closed",
"rollback_integrity_pass",
"validator_and_state_machine_tests_pass",
"protection_compare_and_swap_pass",
"positive_and_negative_governance_tests_pass",
"production_write_false"
],
"pre_activation_protection_snapshot": {
"protected_branch": [
{
"approvals_whitelist_team_i_ds": "null",
"approvals_whitelist_user_i_ds": "[42,43]",
"block_on_official_review_requests": 1,
"block_on_outdated_branch": 1,
"block_on_rejected_reviews": 1,
"branch_name": "governance/approvals",
"can_push": 0,
"created_unix": 1785093201,
"dismiss_stale_approvals": 1,
"enable_approvals_whitelist": 1,
"enable_merge_whitelist": 1,
"enable_status_check": 0,
"enable_whitelist": 0,
"id": 1,
"ignore_stale_approvals": 0,
"merge_whitelist_team_i_ds": "null",
"merge_whitelist_user_i_ds": "[42,43]",
"protected_file_patterns": "",
"repo_id": 1,
"require_signed_commits": 0,
"required_approvals": 2,
"status_check_contexts": "[]",
"unprotected_file_patterns": "",
"updated_unix": 1785093422,
"whitelist_deploy_keys": 0,
"whitelist_team_i_ds": "null",
"whitelist_user_i_ds": "null"
},
{
"approvals_whitelist_team_i_ds": "null",
"approvals_whitelist_user_i_ds": "[42,43]",
"block_on_official_review_requests": 1,
"block_on_outdated_branch": 1,
"block_on_rejected_reviews": 1,
"branch_name": "integration/chatgpt-autonomous-completion-20260726",
"can_push": 0,
"created_unix": 1785093201,
"dismiss_stale_approvals": 1,
"enable_approvals_whitelist": 1,
"enable_merge_whitelist": 1,
"enable_status_check": 0,
"enable_whitelist": 0,
"id": 3,
"ignore_stale_approvals": 0,
"merge_whitelist_team_i_ds": "null",
"merge_whitelist_user_i_ds": "[42,43]",
"protected_file_patterns": "",
"repo_id": 1,
"require_signed_commits": 0,
"required_approvals": 2,
"status_check_contexts": "[]",
"unprotected_file_patterns": "",
"updated_unix": 1785093422,
"whitelist_deploy_keys": 0,
"whitelist_team_i_ds": "null",
"whitelist_user_i_ds": "null"
},
{
"approvals_whitelist_team_i_ds": "null",
"approvals_whitelist_user_i_ds": "[42,43]",
"block_on_official_review_requests": 1,
"block_on_outdated_branch": 1,
"block_on_rejected_reviews": 1,
"branch_name": "main",
"can_push": 0,
"created_unix": 1785093201,
"dismiss_stale_approvals": 1,
"enable_approvals_whitelist": 1,
"enable_merge_whitelist": 1,
"enable_status_check": 0,
"enable_whitelist": 0,
"id": 2,
"ignore_stale_approvals": 0,
"merge_whitelist_team_i_ds": "null",
"merge_whitelist_user_i_ds": "[42,43]",
"protected_file_patterns": "",
"repo_id": 1,
"require_signed_commits": 0,
"required_approvals": 2,
"status_check_contexts": "[]",
"unprotected_file_patterns": "",
"updated_unix": 1785093422,
"whitelist_deploy_keys": 0,
"whitelist_team_i_ds": "null",
"whitelist_user_i_ds": "null"
}
],
"protected_tag": []
},
"pre_activation_protection_snapshot_sha256": "2bc353f34689242cabebf89856d3faab0e1c496b5d33761dfb7cbd47904516f7",
"pre_approval_non_authorizations": {
"baseline_write_allowed": false,
"branch_protection_update_allowed": false,
"control_plane_activation_allowed": false,
"development_allowed": false,
"integration_write_allowed": false,
"main_write_allowed": false,
"merge_allowed": false,
"mirror_allowed": false,
"production_write_allowed": false,
"registry_write_allowed": false,
"rollback_install_allowed": false,
"standing_writer_allowed": false,
"state_machine_update_allowed": false,
"tag_write_allowed": false,
"validator_update_allowed": false
},
"ratification_scope": "GOVERNANCE_MIGRATION_AND_CONTROL_PLANE_ACTIVATION_ONLY",
"ratifies_pr26_manifest_blob_oid": "65f44007b10fc2a912d69e3f9081c0cfff77dfad",
"ratifies_pr26_manifest_path": "approvals/governance-policy/SINGLE-OWNER-GOVERNANCE-MIGRATION-20260728T162246Z.json",
"ratifies_pr26_manifest_sha256": "c097475afbe3074e6482f125b635981f8c0284f3d763c926e2a63e1a3ee1c6c3",
"ratifies_pr26_merge_oid": "a5489f1b67870622162b2daa781bd0237735831a",
"ratifies_pr26_request_oid": "312d3b483049a748675e887a516ec739c81ff474",
"ratifies_pr26_tree_oid": "5c6974c058bba6210dcc1bdd0968fb7e6c84a844",
"ratifies_pr27_manifest_blob_oid": "77f3c2ab85cba2c30c8c0aa36e591232d0f4c396",
"ratifies_pr27_manifest_path": "approvals/governance-policy/SINGLE-OWNER-GOVERNANCE-CONTROL-PLANE-DEPLOYMENT-20260728T170740Z-ea7a102dac417c23.json",
"ratifies_pr27_manifest_sha256": "2ed09180c0aeadbef2e5d6310efe7c2d0de15e0e87b6135e7a8494cb4f0967c7",
"ratifies_pr27_merge_oid": "4e6ef70029b1d94626e432892f7d3beb8e3e5627",
"ratifies_pr27_request_oid": "80feef309fd8e1db7795f68d5bf0f15ce805b365",
"ratifies_pr27_tree_oid": "85af0d1e88e8484a9c3a0562a81cbc1de09250ae",
"ratifies_pr_numbers": [
26,
27
],
"repository": "aios/aios",
"request_status": "HUMAN_OWNER_APPROVAL_PENDING",
"retroactive_authorization_for_other_operations": false,
"rollback_archive_member_hashes": {
"pre-migration-backup/app.ini": "0693e4fa8296a22533429339faeee2ac1856b6c966c6c1009bb139ab4784f687",
"pre-migration-backup/authoritative-aios.bundle": "4fb4ccc979c3061065cde451af0e733326cb56fa6f860124bb73f153a60907c9",
"pre-migration-backup/authoritative-refs.txt": "85cb664c8edf3902bebfc6c2253a3ee16cff8534f86561ba771a73df160186c6",
"pre-migration-backup/backup-metadata.json": "a38ef6dacb52ae61c4332bf8d087f479fb0d5f51d5f636a132a711bddd6e7732",
"pre-migration-backup/checksums.sha256": "72e2fe0b03d1011c872bb39a6cff489f08398ac7d52092f720cbbc63bcf6f753",
"pre-migration-backup/gitea-aios.bundle": "a343c7437f3a1a2aa842dd9d986a1d3cf80691058faae978565224320ff5ed90",
"pre-migration-backup/gitea-refs.txt": "1792b2c4f1cf1f232704601ee968e16425f926a6eaab1bdcddf273525d046e4d",
"pre-migration-backup/gitea.db": "aadcc1587a05827ed3b2c4ffc2403f26139020cd0328afaa03f7afbf6083a2f1",
"pre-migration-backup/governance-identities.json": "2d7b4e72d1fdf187425092089589547e0d76784c611d00f915a8c212f17d3b15",
"pre-migration-backup/protected-branch.json": "5cc4ae4fe5614baa3d4bb83d71872a4ad1ce3c5e39061e02b336be40d5b5b75d",
"pre-migration-backup/protected-tag.json": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"pre-migration-backup/repository/active-runtime/app/aios_isolated_writer_policy.py": "d86ec23fd5d8b7e9844c0895c50385b6f8f3071c3dac3c0f26c70768ae00a188",
"pre-migration-backup/repository/active-runtime/app/isolated_writer_authz.py": "cfae1cdf70c1dabbe013e9365c308a45f11acf20035881a3bb6143774682bbf0",
"pre-migration-backup/repository/active-runtime/app/isolated_writer_path_policy.py": "c6c9ea8e45dfc03c4703503f4dc9c92f887bbacdbf1c7779a487567eee6c257c",
"pre-migration-backup/repository/active-runtime/app/silent_release_controller.py": "524a0a9961b15c2a35b669d1b89b2142377c13ddd3c721780f374331b7d2b6eb",
"pre-migration-backup/repository/active-runtime/app/silent_release_hardening.py": "524aba7034f2cd89d897fe01e9799c835bae9f11ca738182ce469aa59e05cc1a",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/approval.py": "cc937a81aef881206cb1d6fd2ad1feb1a1c2e0ad91c908095d56fd96402c3373",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/models.py": "aa3b3dd41c03c17e4e116ce444d9f4f779694a9cde684e8329cf892bd319069a",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/policy.py": "24b3f3326e6dcd1a4c376d892c53ad20c68e0dd6f861a3a34e11c9a2bba4c756",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/release.py": "db535e5006f8e4a3ab80c2f689213045c120b01cda9b43ef461a3022096c9d19",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/store.py": "31e1f3b904b0bfc8822d21bfd166a45388f122398d1ec76b803e90ee06dc92f0",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/workflow.py": "5f6a8e3a4d66f47717e95842f2eaa443e3cfa321cb08026cc82d74c4ad353bcf",
"pre-migration-backup/repository/tests/autonomous_release/test_core_contracts.py": "71852070db50a04901c141213cadc987ae17ec678fe27a901fee165b6d1c3e2a",
"pre-migration-backup/repository/tests/autonomous_release/test_external_gates.py": "91cca37eb1d40f0cf9fc38b12e2123045ffebd794a34d6cdef3f1dec470fffd2",
"pre-migration-backup/repository/tests/autonomous_release/test_release_gates.py": "d82b23ac00f5389f1a0de628bda9dff898d33f80d375cf6ff74f1531fd138134",
"pre-migration-backup/repository/tests/autonomous_release/test_state_and_workflow.py": "c0395a901732adb0b2f1402e6a1cf5202d54aa597bcaec9584a7ea7589c53917"
},
"rollback_configuration_path": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-MIGRATION-20260729/rollback-configuration.tar",
"rollback_configuration_sha256": "fc8dcf68aaf53edb0cda45833ee45ba5b8b205791af9073258ca617c8b8187d6",
"schema": "aios.single-owner-governance-final-owner-ratification/v1",
"single_owner_policy_effective_at": "FINAL_RATIFICATION_MERGE_OID",
"task_id": "AIOS-SINGLE-OWNER-GOVERNANCE-FINAL-RATIFICATION-20260729"
}
@@ -0,0 +1,484 @@
{
"allowed_human_approvers": [
"owner"
],
"approval_expires_at": "2026-07-29T16:22:46Z",
"approval_request_branch": "governance/request/single-owner-governance-migration-20260728T162246Z",
"approval_type": "SINGLE_OWNER_GOVERNANCE_POLICY",
"approval_types_migrated_after_policy_effective_at": [
"SOURCE_MAPPING_AND_IMPORT_EXECUTION_RENEWAL",
"CONTROL_PLANE_DEPLOYMENT_APPROVAL",
"DEVELOPMENT_MERGE_APPROVAL",
"RELEASE_CANDIDATE_APPROVAL",
"PRODUCTION_RELEASE_APPROVAL",
"TAG_APPROVAL",
"REGISTRY_BASELINE_PROMOTION_APPROVAL",
"PRODUCTION_DEPLOYMENT_APPROVAL",
"ROLLBACK_APPROVAL"
],
"atomic_migration": {
"backup_checksums_sha256": "72e2fe0b03d1011c872bb39a6cff489f08398ac7d52092f720cbbc63bcf6f753",
"backup_root": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-MIGRATION-20260729/pre-migration-backup",
"direct_database_update": false,
"direct_ref_update": false,
"dual_capable_validator_shadow_required": true,
"identity_snapshot_sha256": "2d7b4e72d1fdf187425092089589547e0d76784c611d00f915a8c212f17d3b15",
"live_protection_canonical_sha256": "2bc353f34689242cabebf89856d3faab0e1c496b5d33761dfb7cbd47904516f7",
"maintenance_lock_required": true,
"old_rules_remain_active_until_owner_approval_and_machine_gates_pass": true,
"protected_branch_snapshot_sha256": "2bc353f34689242cabebf89856d3faab0e1c496b5d33761dfb7cbd47904516f7",
"protection_update_method": "authenticated_admin_API_compare_and_swap",
"reviewable_backup_file_hashes": {
"app.ini": "0693e4fa8296a22533429339faeee2ac1856b6c966c6c1009bb139ab4784f687",
"authoritative-aios.bundle": "4fb4ccc979c3061065cde451af0e733326cb56fa6f860124bb73f153a60907c9",
"authoritative-refs.txt": "85cb664c8edf3902bebfc6c2253a3ee16cff8534f86561ba771a73df160186c6",
"backup-metadata.json": "a38ef6dacb52ae61c4332bf8d087f479fb0d5f51d5f636a132a711bddd6e7732",
"checksums.sha256": "72e2fe0b03d1011c872bb39a6cff489f08398ac7d52092f720cbbc63bcf6f753",
"gitea-aios.bundle": "a343c7437f3a1a2aa842dd9d986a1d3cf80691058faae978565224320ff5ed90",
"gitea-refs.txt": "1792b2c4f1cf1f232704601ee968e16425f926a6eaab1bdcddf273525d046e4d",
"gitea.db": "aadcc1587a05827ed3b2c4ffc2403f26139020cd0328afaa03f7afbf6083a2f1",
"governance-identities.json": "2d7b4e72d1fdf187425092089589547e0d76784c611d00f915a8c212f17d3b15",
"protected-branch.json": "5cc4ae4fe5614baa3d4bb83d71872a4ad1ce3c5e39061e02b336be40d5b5b75d",
"protected-tag.json": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"repository/active-runtime/app/aios_isolated_writer_policy.py": "d86ec23fd5d8b7e9844c0895c50385b6f8f3071c3dac3c0f26c70768ae00a188",
"repository/active-runtime/app/isolated_writer_authz.py": "cfae1cdf70c1dabbe013e9365c308a45f11acf20035881a3bb6143774682bbf0",
"repository/active-runtime/app/isolated_writer_path_policy.py": "c6c9ea8e45dfc03c4703503f4dc9c92f887bbacdbf1c7779a487567eee6c257c",
"repository/active-runtime/app/silent_release_controller.py": "524a0a9961b15c2a35b669d1b89b2142377c13ddd3c721780f374331b7d2b6eb",
"repository/active-runtime/app/silent_release_hardening.py": "524aba7034f2cd89d897fe01e9799c835bae9f11ca738182ce469aa59e05cc1a",
"repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/approval.py": "cc937a81aef881206cb1d6fd2ad1feb1a1c2e0ad91c908095d56fd96402c3373",
"repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/models.py": "aa3b3dd41c03c17e4e116ce444d9f4f779694a9cde684e8329cf892bd319069a",
"repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/policy.py": "24b3f3326e6dcd1a4c376d892c53ad20c68e0dd6f861a3a34e11c9a2bba4c756",
"repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/release.py": "db535e5006f8e4a3ab80c2f689213045c120b01cda9b43ef461a3022096c9d19",
"repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/store.py": "31e1f3b904b0bfc8822d21bfd166a45388f122398d1ec76b803e90ee06dc92f0",
"repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/workflow.py": "5f6a8e3a4d66f47717e95842f2eaa443e3cfa321cb08026cc82d74c4ad353bcf",
"repository/tests/autonomous_release/test_core_contracts.py": "71852070db50a04901c141213cadc987ae17ec678fe27a901fee165b6d1c3e2a",
"repository/tests/autonomous_release/test_external_gates.py": "91cca37eb1d40f0cf9fc38b12e2123045ffebd794a34d6cdef3f1dec470fffd2",
"repository/tests/autonomous_release/test_release_gates.py": "d82b23ac00f5389f1a0de628bda9dff898d33f80d375cf6ff74f1531fd138134",
"repository/tests/autonomous_release/test_state_and_workflow.py": "c0395a901732adb0b2f1402e6a1cf5202d54aa597bcaec9584a7ea7589c53917"
},
"reviewable_pre_migration_governance_identity_snapshot": [
{
"created_unix": 1783321252,
"id": 1,
"is_active": 1,
"is_admin": 0,
"last_login_unix": 0,
"lower_name": "aios",
"prohibit_login": 1,
"type": 0
},
{
"created_unix": 1783335380,
"id": 2,
"is_active": 1,
"is_admin": 1,
"last_login_unix": 1785086126,
"lower_name": "owner",
"prohibit_login": 0,
"type": 0
},
{
"created_unix": 1783411566,
"id": 3,
"is_active": 1,
"is_admin": 1,
"last_login_unix": 0,
"lower_name": "gito",
"prohibit_login": 0,
"type": 0
},
{
"created_unix": 1785078826,
"id": 42,
"is_active": 1,
"is_admin": 0,
"last_login_unix": 1785206253,
"lower_name": "codex",
"prohibit_login": 0,
"type": 0
},
{
"created_unix": 1785078882,
"id": 43,
"is_active": 1,
"is_admin": 0,
"last_login_unix": 1785206380,
"lower_name": "gpt",
"prohibit_login": 0,
"type": 0
}
],
"reviewable_pre_migration_protection_snapshot": {
"protected_branch": [
{
"approvals_whitelist_team_i_ds": "null",
"approvals_whitelist_user_i_ds": "[42,43]",
"block_on_official_review_requests": 1,
"block_on_outdated_branch": 1,
"block_on_rejected_reviews": 1,
"branch_name": "governance/approvals",
"can_push": 0,
"created_unix": 1785093201,
"dismiss_stale_approvals": 1,
"enable_approvals_whitelist": 1,
"enable_merge_whitelist": 1,
"enable_status_check": 0,
"enable_whitelist": 0,
"id": 1,
"ignore_stale_approvals": 0,
"merge_whitelist_team_i_ds": "null",
"merge_whitelist_user_i_ds": "[42,43]",
"protected_file_patterns": "",
"repo_id": 1,
"require_signed_commits": 0,
"required_approvals": 2,
"status_check_contexts": "[]",
"unprotected_file_patterns": "",
"updated_unix": 1785093422,
"whitelist_deploy_keys": 0,
"whitelist_team_i_ds": "null",
"whitelist_user_i_ds": "null"
},
{
"approvals_whitelist_team_i_ds": "null",
"approvals_whitelist_user_i_ds": "[42,43]",
"block_on_official_review_requests": 1,
"block_on_outdated_branch": 1,
"block_on_rejected_reviews": 1,
"branch_name": "integration/chatgpt-autonomous-completion-20260726",
"can_push": 0,
"created_unix": 1785093201,
"dismiss_stale_approvals": 1,
"enable_approvals_whitelist": 1,
"enable_merge_whitelist": 1,
"enable_status_check": 0,
"enable_whitelist": 0,
"id": 3,
"ignore_stale_approvals": 0,
"merge_whitelist_team_i_ds": "null",
"merge_whitelist_user_i_ds": "[42,43]",
"protected_file_patterns": "",
"repo_id": 1,
"require_signed_commits": 0,
"required_approvals": 2,
"status_check_contexts": "[]",
"unprotected_file_patterns": "",
"updated_unix": 1785093422,
"whitelist_deploy_keys": 0,
"whitelist_team_i_ds": "null",
"whitelist_user_i_ds": "null"
},
{
"approvals_whitelist_team_i_ds": "null",
"approvals_whitelist_user_i_ds": "[42,43]",
"block_on_official_review_requests": 1,
"block_on_outdated_branch": 1,
"block_on_rejected_reviews": 1,
"branch_name": "main",
"can_push": 0,
"created_unix": 1785093201,
"dismiss_stale_approvals": 1,
"enable_approvals_whitelist": 1,
"enable_merge_whitelist": 1,
"enable_status_check": 0,
"enable_whitelist": 0,
"id": 2,
"ignore_stale_approvals": 0,
"merge_whitelist_team_i_ds": "null",
"merge_whitelist_user_i_ds": "[42,43]",
"protected_file_patterns": "",
"repo_id": 1,
"require_signed_commits": 0,
"required_approvals": 2,
"status_check_contexts": "[]",
"unprotected_file_patterns": "",
"updated_unix": 1785093422,
"whitelist_deploy_keys": 0,
"whitelist_team_i_ds": "null",
"whitelist_user_i_ds": "null"
}
],
"protected_tag": []
},
"rollback_archive_members": {
"pre-migration-backup/app.ini": "0693e4fa8296a22533429339faeee2ac1856b6c966c6c1009bb139ab4784f687",
"pre-migration-backup/authoritative-aios.bundle": "4fb4ccc979c3061065cde451af0e733326cb56fa6f860124bb73f153a60907c9",
"pre-migration-backup/authoritative-refs.txt": "85cb664c8edf3902bebfc6c2253a3ee16cff8534f86561ba771a73df160186c6",
"pre-migration-backup/backup-metadata.json": "a38ef6dacb52ae61c4332bf8d087f479fb0d5f51d5f636a132a711bddd6e7732",
"pre-migration-backup/checksums.sha256": "72e2fe0b03d1011c872bb39a6cff489f08398ac7d52092f720cbbc63bcf6f753",
"pre-migration-backup/gitea-aios.bundle": "a343c7437f3a1a2aa842dd9d986a1d3cf80691058faae978565224320ff5ed90",
"pre-migration-backup/gitea-refs.txt": "1792b2c4f1cf1f232704601ee968e16425f926a6eaab1bdcddf273525d046e4d",
"pre-migration-backup/gitea.db": "aadcc1587a05827ed3b2c4ffc2403f26139020cd0328afaa03f7afbf6083a2f1",
"pre-migration-backup/governance-identities.json": "2d7b4e72d1fdf187425092089589547e0d76784c611d00f915a8c212f17d3b15",
"pre-migration-backup/protected-branch.json": "5cc4ae4fe5614baa3d4bb83d71872a4ad1ce3c5e39061e02b336be40d5b5b75d",
"pre-migration-backup/protected-tag.json": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
"pre-migration-backup/repository/active-runtime/app/aios_isolated_writer_policy.py": "d86ec23fd5d8b7e9844c0895c50385b6f8f3071c3dac3c0f26c70768ae00a188",
"pre-migration-backup/repository/active-runtime/app/isolated_writer_authz.py": "cfae1cdf70c1dabbe013e9365c308a45f11acf20035881a3bb6143774682bbf0",
"pre-migration-backup/repository/active-runtime/app/isolated_writer_path_policy.py": "c6c9ea8e45dfc03c4703503f4dc9c92f887bbacdbf1c7779a487567eee6c257c",
"pre-migration-backup/repository/active-runtime/app/silent_release_controller.py": "524a0a9961b15c2a35b669d1b89b2142377c13ddd3c721780f374331b7d2b6eb",
"pre-migration-backup/repository/active-runtime/app/silent_release_hardening.py": "524aba7034f2cd89d897fe01e9799c835bae9f11ca738182ce469aa59e05cc1a",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/approval.py": "cc937a81aef881206cb1d6fd2ad1feb1a1c2e0ad91c908095d56fd96402c3373",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/models.py": "aa3b3dd41c03c17e4e116ce444d9f4f779694a9cde684e8329cf892bd319069a",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/policy.py": "24b3f3326e6dcd1a4c376d892c53ad20c68e0dd6f861a3a34e11c9a2bba4c756",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/release.py": "db535e5006f8e4a3ab80c2f689213045c120b01cda9b43ef461a3022096c9d19",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/store.py": "31e1f3b904b0bfc8822d21bfd166a45388f122398d1ec76b803e90ee06dc92f0",
"pre-migration-backup/repository/services/aios-autonomous-release-candidate/aios_autonomous_release_candidate/workflow.py": "5f6a8e3a4d66f47717e95842f2eaa443e3cfa321cb08026cc82d74c4ad353bcf",
"pre-migration-backup/repository/tests/autonomous_release/test_core_contracts.py": "71852070db50a04901c141213cadc987ae17ec678fe27a901fee165b6d1c3e2a",
"pre-migration-backup/repository/tests/autonomous_release/test_external_gates.py": "91cca37eb1d40f0cf9fc38b12e2123045ffebd794a34d6cdef3f1dec470fffd2",
"pre-migration-backup/repository/tests/autonomous_release/test_release_gates.py": "d82b23ac00f5389f1a0de628bda9dff898d33f80d375cf6ff74f1531fd138134",
"pre-migration-backup/repository/tests/autonomous_release/test_state_and_workflow.py": "c0395a901732adb0b2f1402e6a1cf5202d54aa597bcaec9584a7ea7589c53917"
},
"rollback_configuration_path": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-MIGRATION-20260729/rollback-configuration.tar",
"rollback_configuration_sha256": "fc8dcf68aaf53edb0cda45833ee45ba5b8b205791af9073258ca617c8b8187d6",
"rollback_restores_protection_before_validator": true
},
"auto_merge_after_owner_approval": false,
"auto_merge_machine_conditions": [
"owner_approval_valid",
"head_oid_unchanged",
"required_checks_pass",
"secret_scan_pass",
"evidence_closure_pass",
"approval_not_expired",
"protected_branch_rules_pass"
],
"automatic_renewal_policy": {
"approval_ref_fast_forward_descendant_required": true,
"changed_condition_fallback": "HUMAN_OWNER_APPROVAL_PENDING",
"secret_scan": "PASS_REQUIRED",
"single_renewal_max_hours": 12,
"status": "PROPOSED_AFTER_MIGRATION",
"total_window_max_days": 7,
"unchanged_fields_required": [
"original_policy_sha256",
"allowed_paths",
"allowed_operations",
"denied_operations",
"source_sha256",
"source_blob_oid"
]
},
"break_glass_executor_may_merge_only_after_owner_approval_machine_gates_and_atomic_cutover_preconditions": true,
"break_glass_expires_at": "2026-07-29T16:22:46Z",
"desired_branch_protection": {
"approval_whitelist_user_ids": [
2
],
"approval_whitelist_usernames": [
"owner"
],
"block_on_official_review_requests": true,
"block_on_outdated_branch": true,
"block_on_rejected_reviews": true,
"branch_deletion": false,
"branch_patterns": [
"governance/approvals",
"main",
"release/**",
"integration/**"
],
"direct_push": false,
"dismiss_stale_approvals": true,
"force_push": false,
"require_status_checks": true,
"required_approvals": 1,
"required_status_contexts": [
"aios/machine-gates",
"aios/secret-scan",
"aios/evidence-closure"
],
"wip_blocks_merge": true
},
"executor_must_not_approve": true,
"expected_governance_base_oid": "ac2dc5c30eb35748ef11c98297812729d0fd5828",
"expires_at": "2026-07-29T16:22:46Z",
"global_constraints": {
"AIOS_GITOPS_WRITES_ENABLED": false,
"approval_impersonation": false,
"direct_main_push": false,
"fake_review": false,
"force_push": false,
"production_change_without_owner_approval": false,
"secret_commit": false,
"tag_rewrite": false
},
"governance_model": "SINGLE_OWNER_WITH_MACHINE_GATES_V1",
"historical_policy": {
"historical_manifests_modified": false,
"old_policy_decoder_retained_read_only": true,
"requests_created_before_policy_effective_at_use_old_policy": true
},
"issued_at": "2026-07-28T16:22:46Z",
"machine_gates": {
"development_branch": [
"allowed_branch",
"allowed_paths",
"compileall",
"targeted_tests",
"secret_scan",
"git_diff_check"
],
"production": [
"owner_approval",
"tag_consistency",
"registry_consistency",
"deployment_plan",
"rollback_plan",
"artifact_integrity",
"production_preflight"
],
"protected_branch_merge": [
"expected_base_oid",
"current_head_oid",
"ordinary_merge_commit",
"parent_order_verified",
"artifact_binding",
"audit_chain_valid"
],
"release": [
"version_manifest",
"explicit_release_target_oid",
"artifact_sha256",
"rollback_artifact_sha256",
"sbom",
"test_evidence",
"evidence_closure"
]
},
"merge_mode": "CREATE_MERGE_COMMIT",
"migration_acceptance_tests": [
"agent_request_pass",
"owner_current_head_approval_pass",
"machine_gates_then_merge_commit_pass",
"agent_self_approval_denied",
"non_owner_approval_denied",
"stale_head_approval_denied",
"wip_merge_denied",
"machine_test_failure_merge_denied",
"secret_scan_failure_merge_denied",
"main_direct_write_denied",
"tag_direct_write_denied",
"force_push_denied",
"missing_tag_target_oid_denied",
"missing_evidence_closure_oid_denied",
"production_without_owner_denied",
"dormant_only_production_activation_denied"
],
"migration_mode": "OWNER_BREAK_GLASS_GOVERNANCE_RESET",
"new_policy": "SINGLE_OWNER_WITH_MACHINE_GATES_V1",
"old_policy": "DUAL_HUMAN_APPROVAL",
"owner_approval_contract": {
"dismissed": false,
"does_not_claim_old_dual_approval_compliance": true,
"head_change_invalidates_owner_approval": true,
"owner_review_is_break_glass_signature": true,
"review_created_before_approval_expires_at": true,
"review_state": "APPROVED",
"reviewed_head_oid_must_equal_current_pr_head_oid": true,
"reviewer_must_equal": "owner",
"stale": false
},
"owner_break_glass_declaration_to_be_attested_by_review": {
"attestation_status": "PENDING_OWNER_REVIEW",
"expires_at": "2026-07-29T16:22:46Z",
"new_policy": "SINGLE_OWNER_WITH_MACHINE_GATES_V1",
"old_policy": "DUAL_HUMAN_APPROVAL",
"owner_acknowledges_old_policy_exception": true,
"reason": "single-maintainer-system",
"scope": "governance-policy-migration-only"
},
"owner_is_only_human_approver": true,
"policy_effective_at": null,
"pre_approval_non_authorizations": {
"approval_validator_update_allowed": false,
"gitea_branch_protection_update_allowed": false,
"merge_allowed": false,
"old_dual_rule_disable_allowed": false,
"production_change_allowed": false,
"state_machine_update_allowed": false,
"writer_credential_issue_allowed": false
},
"prohibited_merge_modes": [
"squash",
"rebase",
"force",
"fast_forward_policy_bypass"
],
"reason": "single-maintainer-system",
"repository": "aios/aios",
"request_status": "HUMAN_OWNER_APPROVAL_PENDING",
"requester_must_not_approve": true,
"requesters": [
"codex-chartgpt-bridge",
"aios-governance-agent",
"aios-release-agent",
"aios-governed-development-writer"
],
"required_distinct_human_approvers": 1,
"required_human_approvals": 1,
"required_owner_approvals": 1,
"resolved_owner": {
"confidence_before_review": "MEDIUM",
"confirmation_rule": "valid APPROVED review by owner on this exact immutable head",
"email_sha256": "f5dc2928f6202c24fa4db8bb33db84e1b77c6eff30d1b95abdadeaae209bc4c9",
"identity_source": [
"gitea_repository_owner_account_aios_is_login_prohibited",
"all_login_enabled_site_admins_enumerated_owner_and_never_logged_in_service_gito",
"only_interactive_site_admin_named_owner",
"gitea_owner_last_login_present",
"historical_governance_records_use_approved_by_role_owner",
"user_declared_single_natural_person_maintainer"
],
"login_enabled_site_admins": [
{
"observed_prior_login": true,
"user_id": 2,
"username": "owner"
},
{
"classification": "service_admin_not_human_approver",
"observed_prior_login": false,
"user_id": 3,
"username": "gito"
}
],
"user_id": 2,
"username": "owner"
},
"schema": "aios.single-owner-governance-policy/v1",
"scope": "governance-policy-migration-only",
"standing_autonomous_development_policy": {
"allowed_without_repeated_owner_approval": [
"patch_branch_create",
"allowlisted_development_write",
"patch_branch_commit_and_push",
"test_execute",
"artifact_build",
"approval_pr_create",
"read_only_evidence",
"task_writer_renewal"
],
"owner_approval_still_required": [
"protected_branch_merge",
"tag",
"registry_update",
"production_baseline_update",
"production_deploy",
"production_rollback",
"governance_policy_change"
],
"status": "PROPOSED_AFTER_MIGRATION"
},
"standing_single_owner_governance_migration_authorization": true,
"state_machine": {
"auto_merge_ready_state": "AUTO_MERGE_READY",
"execution_ready_state": "OWNER_APPROVED_EXECUTION_READY",
"machine_verified_state": "MACHINE_GATES_VERIFIED",
"owner_approval_alone_is_not_execution_ready": true,
"owner_verified_state": "OWNER_APPROVAL_VERIFIED",
"pending_state": "HUMAN_OWNER_APPROVAL_PENDING"
},
"task_id": "AIOS-SINGLE-OWNER-GOVERNANCE-MIGRATION-20260729",
"this_manifest_authorizes_only_governance_policy_migration": true,
"this_manifest_grants_standing_development_authorization": false
}
@@ -0,0 +1,49 @@
{
"schema": "aios.gitea-native-approval/v1",
"approval_type": "IMPLEMENTATION",
"task_id": "AIOS-INTEGRATION-REFRESH-PROVISIONER-IMPLEMENTATION-20260726",
"repository": "aios/aios",
"branch": "patch/integration-refresh-grant-provisioner-20260726",
"base_oid": "875d41c3101093149414292067fd700dc214d4d3",
"actor_identity": "chatgpt-gitops-bot",
"writer_audience": "aios-integration-refresh-provisioner-development-writer",
"risk": "high",
"allowed_paths": [
"active-runtime/app/**",
"tests/test_integration_refresh_provisioner.py",
"tests/test_isolated_writer_integration_merge.py",
"tests/test_gitea_branch_read_projection.py",
"tests/test_isolated_writer_token_policy_v2.py",
"deploy/systemd/aios-integration-refresh-*.service",
"docs/autonomous-release/**"
],
"allowed_operations": [
"repository.source_map.read",
"runtime.unit_metadata.read",
"git.ref.read",
"git.diff.read",
"git.branch.patch.create",
"commit_file.atomic",
"git.push.patch_branch",
"test.execute.allowlisted",
"artifact.build.control_plane_patch",
"evidence.write.task_runtime"
],
"denied_operations": [
"main.write",
"main.merge",
"tag.write",
"tag.delete",
"tag.rewrite",
"force_push",
"history.rewrite",
"baseline.write",
"registry.write",
"production.deploy",
"production.rollback",
"secret.read",
"secret.export",
"bare_ref_direct_write"
],
"expires_at": "2026-07-27T03:35:55Z"
}
@@ -0,0 +1,49 @@
{
"schema": "aios.gitea-native-approval/v1",
"approval_type": "IMPLEMENTATION",
"task_id": "AIOS-INTEGRATION-REFRESH-PROVISIONER-IMPLEMENTATION-20260726",
"repository": "aios/aios",
"branch": "patch/integration-refresh-grant-provisioner-20260726",
"base_oid": "875d41c3101093149414292067fd700dc214d4d3",
"actor_identity": "chatgpt-gitops-bot",
"writer_audience": "aios-integration-refresh-provisioner-development-writer",
"risk": "high",
"allowed_paths": [
"active-runtime/app/**",
"tests/test_integration_refresh_provisioner.py",
"tests/test_isolated_writer_integration_merge.py",
"tests/test_gitea_branch_read_projection.py",
"tests/test_isolated_writer_token_policy_v2.py",
"deploy/systemd/aios-integration-refresh-*.service",
"docs/autonomous-release/**"
],
"allowed_operations": [
"repository.source_map.read",
"runtime.unit_metadata.read",
"git.ref.read",
"git.diff.read",
"git.branch.patch.create",
"commit_file.atomic",
"git.push.patch_branch",
"test.execute.allowlisted",
"artifact.build.control_plane_patch",
"evidence.write.task_runtime"
],
"denied_operations": [
"main.write",
"main.merge",
"tag.write",
"tag.delete",
"tag.rewrite",
"force_push",
"history.rewrite",
"baseline.write",
"registry.write",
"production.deploy",
"production.rollback",
"secret.read",
"secret.export",
"bare_ref_direct_write"
],
"expires_at": "2026-07-27T13:00:11Z"
}
@@ -0,0 +1,73 @@
{
"approval_type": "SINGLE_OWNER_GOVERNANCE_LIVE_ACTIVATION_IMPLEMENTATION_AND_EXECUTION",
"artifact_sha256": "01e0226f0302bb8e2f8d81299393075bf0332c6e22e00877469fb297c51f3802",
"authorization_scope": [
"deploy_live_activation_implementation",
"execute_one_atomic_governance_activation",
"execute_acceptance_tests",
"control_plane_rollback_on_failure",
"write_activation_receipt"
],
"denied_operations": [
"main.write",
"integration.write",
"tag.write",
"registry.write",
"baseline.write",
"production.deploy",
"force_push",
"history_rewrite"
],
"evidence_closure_oid": "c6316943d2485f06f97242df6338ded21de1ee38",
"evidence_closure_sha256": "bd521103c907d6194acbbbd42a947c5af2ccbda91797e5dc75e81887a042becd",
"execution_binding": {
"backend": "sqlite",
"branch": "governance/approvals",
"evidence_closure_oid": "c6316943d2485f06f97242df6338ded21de1ee38",
"executor": "aios-governance-single-owner-activation",
"expected_branch_protection_sha256": "f27992c8024426708d93bce072d231707bae47a927aa2393d566aae64d5ed079",
"expected_gitea_schema_sha256": "3524f4912165939cb746c2c65d70583a909f5abbd00c4e07ae76f7206d49aa54",
"expected_state_machine_sha256": "0b08a2c378d143cb9031a25132afc7b7d825bdc03d11efe10610341d4b70167e",
"expected_validator_sha256": "754639846cb15cb997d612a1fe0ceb0224ddef5bbc3ccac9802a3747f122dac1",
"forbidden_operations": {
"baseline": false,
"force_push": false,
"governance_direct": false,
"history_rewrite": false,
"integration": false,
"main": false,
"production": false,
"registry": false,
"tags": false
},
"operation_id": "single-owner-live-activation-20260729T033228Z",
"repo_id": 1,
"requester": "codex-agent",
"target_branch_protection_sha256": "61b424b0c495eed71c73171c5c4434ac66d074de36886a73ec4c445fd1905db8",
"task_id": "AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-20260729"
},
"execution_binding_sha256": "6b2ed671a94fa83704383728fd2bb2df3b67523b4273100fa371777d984be102",
"expected_governance_base_oid": "8b7f9d9028f6ff9beb225bf85f53dbeaac6830e7",
"expires_at": "2026-07-29T15:32:28Z",
"human_authorizer": "owner",
"implementation_commit_oid": "e1e438564ce8b987a36df0947e6eaa324dfede74",
"implementation_tree_oid": "dd93dc1df10cb8b8fe59b09d3214a9ae6fee671e",
"issued_at": "2026-07-29T03:32:28Z",
"legacy_mechanical_approvals": [
"codex",
"gpt"
],
"machine_gate_contexts": [
"aios/branch-protection",
"aios/evidence-closure",
"aios/secret-scan",
"aios/state-machine",
"aios/validator"
],
"pr30_merge_oid": "f6bef90633f428454e85721f353cd82cdf04caf0",
"pr31_merge_oid": "8b7f9d9028f6ff9beb225bf85f53dbeaac6830e7",
"rollback_artifact_sha256": "ed9307cc2f07767b75866fcb370fa3f98b76c5147e4b7fc49ecf04cf21cf7c31",
"signed_merge_requirement_effective": false,
"task_id": "AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-20260729",
"test_evidence_sha256": "172a7cf812c6b901524138fb72851a9b7d2e895dedc98893407d0bab9b52c6c1"
}
@@ -0,0 +1,171 @@
{
"approval_type": "SINGLE_OWNER_GOVERNANCE_LIVE_ACTIVATION_IMPLEMENTATION_AND_EXECUTION",
"artifact_path": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-20260729/artifacts/hardening-71def340e7cc34f4f19918dcf8d3c847abbe4fbf/live-activation-71def340e7cc34f4f19918dcf8d3c847abbe4fbf.tar.gz",
"artifact_sha256": "32bc49c207ec454b6fd81b0484f5b257bb789481b37175995029a2ec78cc62fa",
"authorization_scope": [
"deploy_exact_approved_artifact",
"publish_exact_head_machine_statuses",
"execute_one_atomic_governance_activation",
"verify_and_rollback_exact_transaction"
],
"denied_operations": [
"main.write",
"integration.write",
"tag.write",
"registry.write",
"baseline.write",
"production.deploy",
"force_push",
"history_rewrite"
],
"evidence_closure_blob_oid": "6af6d017f22c4e0c512b0cd62644cdc6ab2135d5",
"evidence_closure_oid": "310ab2af902a9fde9108d227077f433cc743ce7c",
"evidence_closure_path": "evidence/single-owner-governance/AIOS-SINGLE-OWNER-LIVE-ACTIVATION-HARDENING-20260729T043010Z.json",
"evidence_closure_sha256": "e482fe52c8381f765ee508d2de1fe2e77dff52e6e342f01be4ca481ff2f76820",
"execution_binding": {
"artifact_path": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-20260729/artifacts/hardening-71def340e7cc34f4f19918dcf8d3c847abbe4fbf/live-activation-71def340e7cc34f4f19918dcf8d3c847abbe4fbf.tar.gz",
"artifact_sha256": "32bc49c207ec454b6fd81b0484f5b257bb789481b37175995029a2ec78cc62fa",
"backend": "sqlite",
"branch": "governance/approvals",
"evidence_closure_oid": "310ab2af902a9fde9108d227077f433cc743ce7c",
"evidence_closure_path": "evidence/single-owner-governance/AIOS-SINGLE-OWNER-LIVE-ACTIVATION-HARDENING-20260729T043010Z.json",
"evidence_closure_sha256": "e482fe52c8381f765ee508d2de1fe2e77dff52e6e342f01be4ca481ff2f76820",
"executor": "aios-governance-single-owner-activation",
"expected_branch_protection_sha256": "f27992c8024426708d93bce072d231707bae47a927aa2393d566aae64d5ed079",
"expected_gitea_schema_sha256": "3524f4912165939cb746c2c65d70583a909f5abbd00c4e07ae76f7206d49aa54",
"expected_state_machine_sha256": "0b08a2c378d143cb9031a25132afc7b7d825bdc03d11efe10610341d4b70167e",
"expected_validator_sha256": "754639846cb15cb997d612a1fe0ceb0224ddef5bbc3ccac9802a3747f122dac1",
"forbidden_operations": {
"baseline": false,
"force_push": false,
"governance_direct": false,
"history_rewrite": false,
"integration": false,
"main": false,
"production": false,
"registry": false,
"tags": false
},
"implementation_commit_oid": "71def340e7cc34f4f19918dcf8d3c847abbe4fbf",
"implementation_tree_oid": "3cc61bfbf69cbe0a24d54a0e53a6c50bcc130066",
"machine_status_producer_id": 13,
"machine_status_producer_name": "gitops-bot",
"operation_id": "single-owner-live-activation-hardening-20260729T043149Z",
"repo_id": 1,
"requester": "codex-agent",
"rollback_artifact_path": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-20260729/artifacts/hardening-71def340e7cc34f4f19918dcf8d3c847abbe4fbf/live-activation-rollback-71def340e7cc34f4f19918dcf8d3c847abbe4fbf.tar.gz",
"rollback_artifact_sha256": "4efe1ea73d4fd72e5364fc91a16ad5e9d1e6ebe78d8aa466f7b11c4915b08403",
"runtime_sources": [
{
"git_path": "services/aios-single-owner-governance/aios_single_owner_governance/activation.py",
"runtime_path": "/opt/aios/single-owner-governance/releases/71def340e7cc34f4f19918dcf8d3c847abbe4fbf/services/aios-single-owner-governance/aios_single_owner_governance/activation.py",
"sha256": "48846a58fa3afb2b7c8ffe6e88504a9333863932df867f33ba0321ad3bac6003"
},
{
"git_path": "services/aios-single-owner-governance/aios_single_owner_governance/gitea_protected_branch.py",
"runtime_path": "/opt/aios/single-owner-governance/releases/71def340e7cc34f4f19918dcf8d3c847abbe4fbf/services/aios-single-owner-governance/aios_single_owner_governance/gitea_protected_branch.py",
"sha256": "00775efe3f3d631d88379eff4ed2dcfaf386a2fa43111abe961e75109e80d768"
},
{
"git_path": "services/aios-single-owner-governance/aios_single_owner_governance/journal.py",
"runtime_path": "/opt/aios/single-owner-governance/releases/71def340e7cc34f4f19918dcf8d3c847abbe4fbf/services/aios-single-owner-governance/aios_single_owner_governance/journal.py",
"sha256": "a8f121245e04487d99c99fb03ada83f0c907723f8eb18552872ff46dcf5a7873"
},
{
"git_path": "services/aios-single-owner-governance/aios_single_owner_governance/state_machine.py",
"runtime_path": "/opt/aios/single-owner-governance/releases/71def340e7cc34f4f19918dcf8d3c847abbe4fbf/services/aios-single-owner-governance/aios_single_owner_governance/state_machine.py",
"sha256": "0b08a2c378d143cb9031a25132afc7b7d825bdc03d11efe10610341d4b70167e"
},
{
"git_path": "services/aios-single-owner-governance/aios_single_owner_governance/validator.py",
"runtime_path": "/opt/aios/single-owner-governance/releases/71def340e7cc34f4f19918dcf8d3c847abbe4fbf/services/aios-single-owner-governance/aios_single_owner_governance/validator.py",
"sha256": "754639846cb15cb997d612a1fe0ceb0224ddef5bbc3ccac9802a3747f122dac1"
}
],
"target_branch_protection_sha256": "4713f0494b79103668fbe5bd8fd7da5d60a43e56fb545aa6e7c773f43dc07c10",
"task_id": "AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-20260729",
"test_evidence_path": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-20260729/artifacts/hardening-71def340e7cc34f4f19918dcf8d3c847abbe4fbf/test-evidence-71def340e7cc34f4f19918dcf8d3c847abbe4fbf.json",
"test_evidence_sha256": "c1633732767f3f051ffb01404d12d05a6168a4b01b91efdb34a64988d6dee684"
},
"execution_binding_sha256": "63705dd0f5cc25debde132179f96819a844a9703b33c092db4ac48d5680d536a",
"expected_governance_base_oid": "1071979079deab8a4028473d967c2a205c3b111e",
"expires_at": "2026-07-29T16:31:49Z",
"human_authorizer": "owner",
"implementation_commit_oid": "71def340e7cc34f4f19918dcf8d3c847abbe4fbf",
"implementation_tree_oid": "3cc61bfbf69cbe0a24d54a0e53a6c50bcc130066",
"issued_at": "2026-07-29T04:31:49Z",
"legacy_mechanical_approvals": [
"codex",
"gpt"
],
"machine_gate_contexts": [
"aios/branch-protection",
"aios/evidence-closure",
"aios/secret-scan",
"aios/state-machine",
"aios/validator"
],
"machine_status_producer_id": 13,
"machine_status_producer_name": "gitops-bot",
"rollback_artifact_path": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-20260729/artifacts/hardening-71def340e7cc34f4f19918dcf8d3c847abbe4fbf/live-activation-rollback-71def340e7cc34f4f19918dcf8d3c847abbe4fbf.tar.gz",
"rollback_artifact_sha256": "4efe1ea73d4fd72e5364fc91a16ad5e9d1e6ebe78d8aa466f7b11c4915b08403",
"runtime_sources": [
{
"git_path": "services/aios-single-owner-governance/aios_single_owner_governance/activation.py",
"runtime_path": "/opt/aios/single-owner-governance/releases/71def340e7cc34f4f19918dcf8d3c847abbe4fbf/services/aios-single-owner-governance/aios_single_owner_governance/activation.py",
"sha256": "48846a58fa3afb2b7c8ffe6e88504a9333863932df867f33ba0321ad3bac6003"
},
{
"git_path": "services/aios-single-owner-governance/aios_single_owner_governance/gitea_protected_branch.py",
"runtime_path": "/opt/aios/single-owner-governance/releases/71def340e7cc34f4f19918dcf8d3c847abbe4fbf/services/aios-single-owner-governance/aios_single_owner_governance/gitea_protected_branch.py",
"sha256": "00775efe3f3d631d88379eff4ed2dcfaf386a2fa43111abe961e75109e80d768"
},
{
"git_path": "services/aios-single-owner-governance/aios_single_owner_governance/journal.py",
"runtime_path": "/opt/aios/single-owner-governance/releases/71def340e7cc34f4f19918dcf8d3c847abbe4fbf/services/aios-single-owner-governance/aios_single_owner_governance/journal.py",
"sha256": "a8f121245e04487d99c99fb03ada83f0c907723f8eb18552872ff46dcf5a7873"
},
{
"git_path": "services/aios-single-owner-governance/aios_single_owner_governance/state_machine.py",
"runtime_path": "/opt/aios/single-owner-governance/releases/71def340e7cc34f4f19918dcf8d3c847abbe4fbf/services/aios-single-owner-governance/aios_single_owner_governance/state_machine.py",
"sha256": "0b08a2c378d143cb9031a25132afc7b7d825bdc03d11efe10610341d4b70167e"
},
{
"git_path": "services/aios-single-owner-governance/aios_single_owner_governance/validator.py",
"runtime_path": "/opt/aios/single-owner-governance/releases/71def340e7cc34f4f19918dcf8d3c847abbe4fbf/services/aios-single-owner-governance/aios_single_owner_governance/validator.py",
"sha256": "754639846cb15cb997d612a1fe0ceb0224ddef5bbc3ccac9802a3747f122dac1"
}
],
"target_branch_protection": {
"approvals_whitelist_team_i_ds": "null",
"approvals_whitelist_user_i_ds": "[2]",
"block_on_official_review_requests": 1,
"block_on_outdated_branch": 1,
"block_on_rejected_reviews": 1,
"branch_name": "governance/approvals",
"can_push": 0,
"created_unix": 1785093201,
"dismiss_stale_approvals": 1,
"enable_approvals_whitelist": 1,
"enable_merge_whitelist": 1,
"enable_status_check": 1,
"enable_whitelist": 0,
"id": 1,
"ignore_stale_approvals": 0,
"merge_whitelist_team_i_ds": "null",
"merge_whitelist_user_i_ds": "[42,43]",
"protected_file_patterns": "",
"repo_id": 1,
"require_signed_commits": 0,
"required_approvals": 1,
"status_check_contexts": "[\"aios/branch-protection\",\"aios/evidence-closure\",\"aios/secret-scan\",\"aios/state-machine\",\"aios/validator\"]",
"unprotected_file_patterns": "",
"updated_unix": 1785299509,
"whitelist_deploy_keys": 0,
"whitelist_team_i_ds": "null",
"whitelist_user_i_ds": "null"
},
"task_id": "AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-20260729",
"test_evidence_path": "/var/lib/aios-gitops/runtime/tasks/AIOS-SINGLE-OWNER-GOVERNANCE-ACTIVATION-20260729/artifacts/hardening-71def340e7cc34f4f19918dcf8d3c847abbe4fbf/test-evidence-71def340e7cc34f4f19918dcf8d3c847abbe4fbf.json",
"test_evidence_sha256": "c1633732767f3f051ffb01404d12d05a6168a4b01b91efdb34a64988d6dee684"
}
@@ -0,0 +1,151 @@
{
"actor_identity": "chatgpt-gitops-bot",
"allowed_operations": [
"runtime.source.read.exact",
"runtime.source.hash",
"runtime.unit_metadata.read",
"package.ownership.read",
"git.object.lookup.by_blob_oid",
"secret.scan.local_source",
"repository.source_import.byte_exact",
"repository.module.create",
"source_map.evidence.write",
"git.branch.patch.create",
"commit_file.atomic",
"git.push.patch_branch",
"test.execute.allowlisted",
"artifact.build.control_plane_patch",
"evidence.write.task_runtime"
],
"allowed_paths": [
"active-runtime/app/aios_autonomous_release_authorization/**",
"active-runtime/app/aios_chatgpt_action_task_router/**",
"active-runtime/app/aios_isolated_writer_api/**",
"tests/test_integration_refresh_provisioner.py",
"tests/test_isolated_writer_integration_merge.py",
"tests/test_gitea_branch_read_projection.py",
"tests/test_isolated_writer_token_policy_v2.py",
"deploy/systemd/aios-integration-refresh-*.service",
"docs/autonomous-release/**"
],
"allowed_runtime_reads": [
"/usr/libexec/aios-autonomous-release-authorization/controller.py",
"/usr/libexec/aios-chatgpt-action-task-router-continuous-20260726/action_task_router.py"
],
"approval_type": "SOURCE_MAPPING_AND_IMPORT",
"canonical_paths": {
"controller": "active-runtime/app/aios_autonomous_release_authorization/controller.py",
"isolated_writer_api": "active-runtime/app/aios_isolated_writer_api/**",
"router": "active-runtime/app/aios_chatgpt_action_task_router/action_task_router.py"
},
"denied_operations": [
"secret.value.return",
"secret.matching_line.return",
"secret.context.return",
"runtime.source.modify",
"runtime.unit.modify",
"arbitrary_path.read",
"secret.read.by_agent",
"secret.export",
"main.write",
"main.merge",
"governance.approvals.direct_write",
"integration.write",
"tag.write",
"tag.delete",
"tag.rewrite",
"force_push",
"history.rewrite",
"bare_ref_direct_write",
"baseline.write",
"registry.write",
"production.deploy",
"production.rollback"
],
"expires_at": "2026-07-27T22:36:27Z",
"extends_approval_merge_oid": "45f3226662965c8d41ec1775e8c8857f2b986397",
"finding_policy": {
"controller_byte_exact_import_allowed": true,
"controller_finding_status": "PASS",
"controller_sanitized_source_creation_allowed": false,
"finding_classification_by_automation": "PROHIBITED",
"isolated_writer_api_module_create_allowed": true,
"matching_source_lines_disclosed": false,
"router_byte_exact_import_allowed": true,
"router_finding_status": "PASS",
"router_sanitized_source_creation_allowed": false,
"scan_decision": "MAPPING_IMPORT_ONLY",
"secret_content_disclosed": false
},
"implementation_base_oid": "875d41c3101093149414292067fd700dc214d4d3",
"implementation_branch": "patch/integration-refresh-grant-provisioner-20260726",
"issued_at": "2026-07-27T10:36:27Z",
"repository": "aios/aios",
"required_controls": {
"controller_finding_must_be_resolved": false,
"controller_import_blob_must_equal_runtime_blob": true,
"controller_import_must_be_byte_exact": true,
"controller_import_sha256_must_equal_runtime_sha256": true,
"dual_human_approval_required": true,
"global_gitops_writes_must_remain_disabled": true,
"new_task_bound_grant_required": true,
"old_implementation_token_auth_status": 401,
"old_implementation_writer_revoked": true,
"old_secret_revocation_must_be_verified": false,
"router_finding_must_be_resolved": false,
"router_import_blob_must_equal_runtime_blob": true,
"router_import_must_be_byte_exact": true,
"router_import_sha256_must_equal_runtime_sha256": true,
"sanitized_source_behavioral_equivalence_required": false,
"sanitized_source_secret_scan_must_pass": false,
"true_positive_requires_rotation": false
},
"risk": "high",
"runtime_source_evidence": {
"controller": {
"finding_count": 0,
"findings": [],
"git_blob_oid": "9c68be36e0b6a18260e3099e3d7b0dcab6d814aa",
"group_gid": 0,
"mode": "0o700",
"mtime_ns": 1785043975531298047,
"owner_uid": 0,
"package_owner": "UNPACKAGED",
"referencing_systemd_units": [
"aios-autonomous-release-authorization-controller.service"
],
"resolved_path": "/usr/libexec/aios-autonomous-release-authorization/controller.py",
"secret_content_returned": false,
"secret_scan": "PASS",
"sha256": "39b532c3058c4ae49ed691d7c66c3b7745a25111fa61039f388c8335fd262c50",
"size": 24204,
"utf8_python": true
},
"isolated_writer_api": {
"canonical_source_path": "NOT_ESTABLISHED",
"runtime_module_status": "ABSENT"
},
"router": {
"finding_count": 0,
"findings": [],
"git_blob_oid": "ee0595ca61a0598f8cb3dc10865a255e21679b2a",
"group_gid": 0,
"mode": "0o644",
"mtime_ns": 1785042222580725999,
"owner_uid": 0,
"package_owner": "UNPACKAGED",
"referencing_systemd_units": [
"aios-chatgpt-autonomous-release-route.service"
],
"resolved_path": "/usr/libexec/aios-chatgpt-action-task-router-continuous-20260726/action_task_router.py",
"secret_content_returned": false,
"secret_scan": "PASS",
"sha256": "738fb7035a6b792115d6467b4d1e4ffd47a8c5d5646f7032ebc68ea587cbd554",
"size": 25952,
"utf8_python": true
}
},
"schema": "aios.gitea-native-approval/v1",
"task_id": "AIOS-INTEGRATION-REFRESH-PROVISIONER-IMPLEMENTATION-20260726",
"writer_audience": "aios-integration-refresh-provisioner-development-writer"
}
@@ -0,0 +1,157 @@
{
"actor_identity": "chatgpt-gitops-bot",
"allowed_operations": [
"runtime.source.read.exact",
"runtime.source.hash",
"runtime.unit_metadata.read",
"package.ownership.read",
"git.object.lookup.by_blob_oid",
"secret.scan.local_source",
"repository.source_import.byte_exact",
"repository.module.create",
"source_map.evidence.write",
"git.branch.patch.create",
"commit_file.atomic",
"git.push.patch_branch",
"test.execute.allowlisted",
"artifact.build.control_plane_patch",
"evidence.write.task_runtime"
],
"allowed_paths": [
"active-runtime/app/aios_autonomous_release_authorization/**",
"active-runtime/app/aios_chatgpt_action_task_router/**",
"active-runtime/app/aios_isolated_writer_api/**",
"tests/test_integration_refresh_provisioner.py",
"tests/test_isolated_writer_integration_merge.py",
"tests/test_gitea_branch_read_projection.py",
"tests/test_isolated_writer_token_policy_v2.py",
"deploy/systemd/aios-integration-refresh-*.service",
"docs/autonomous-release/**"
],
"allowed_runtime_reads": [
"/usr/libexec/aios-autonomous-release-authorization/controller.py",
"/usr/libexec/aios-chatgpt-action-task-router-continuous-20260726/action_task_router.py"
],
"approval_type": "SOURCE_MAPPING_AND_IMPORT_EXECUTION_RENEWAL",
"canonical_paths": {
"controller": "active-runtime/app/aios_autonomous_release_authorization/controller.py",
"isolated_writer_api": "active-runtime/app/aios_isolated_writer_api/**",
"router": "active-runtime/app/aios_chatgpt_action_task_router/action_task_router.py"
},
"denied_operations": [
"secret.value.return",
"secret.matching_line.return",
"secret.context.return",
"runtime.source.modify",
"runtime.unit.modify",
"arbitrary_path.read",
"secret.read.by_agent",
"secret.export",
"main.write",
"main.merge",
"governance.approvals.direct_write",
"integration.write",
"tag.write",
"tag.delete",
"tag.rewrite",
"force_push",
"history.rewrite",
"bare_ref_direct_write",
"baseline.write",
"registry.write",
"production.deploy",
"production.rollback"
],
"expected_governance_base_oid": "9514062cf33e45941abe4a8c98377e0713b0b3f6",
"expires_at": "2026-07-28T18:10:44Z",
"extends_approval_merge_oid": "45f3226662965c8d41ec1775e8c8857f2b986397",
"finding_policy": {
"controller_byte_exact_import_allowed": true,
"controller_finding_status": "PASS",
"controller_sanitized_source_creation_allowed": false,
"finding_classification_by_automation": "PROHIBITED",
"isolated_writer_api_module_create_allowed": true,
"matching_source_lines_disclosed": false,
"router_byte_exact_import_allowed": true,
"router_finding_status": "PASS",
"router_sanitized_source_creation_allowed": false,
"scan_decision": "MAPPING_IMPORT_ONLY",
"secret_content_disclosed": false
},
"implementation_base_oid": "875d41c3101093149414292067fd700dc214d4d3",
"implementation_branch": "patch/integration-refresh-grant-provisioner-20260726",
"issued_at": "2026-07-28T06:10:44Z",
"renews_source_mapping_approval_merge_oid": "9514062cf33e45941abe4a8c98377e0713b0b3f6",
"renews_source_mapping_manifest_blob_oid": "00c5e90e529cb98c7750a5761b0a0d6ccf507174",
"renews_source_mapping_manifest_sha256": "17af8ebc43673c0e46bb9ab1bf44497e8c147f1b4a9d7a8a404edd5c0abd6f21",
"repository": "aios/aios",
"required_controls": {
"controller_finding_must_be_resolved": false,
"controller_import_blob_must_equal_runtime_blob": true,
"controller_import_must_be_byte_exact": true,
"controller_import_sha256_must_equal_runtime_sha256": true,
"dual_human_approval_required": true,
"global_gitops_writes_must_remain_disabled": true,
"new_task_bound_grant_required": true,
"old_implementation_token_auth_status": 401,
"old_implementation_writer_revoked": true,
"old_secret_revocation_must_be_verified": false,
"router_finding_must_be_resolved": false,
"router_import_blob_must_equal_runtime_blob": true,
"router_import_must_be_byte_exact": true,
"router_import_sha256_must_equal_runtime_sha256": true,
"sanitized_source_behavioral_equivalence_required": false,
"sanitized_source_secret_scan_must_pass": false,
"true_positive_requires_rotation": false
},
"risk": "high",
"runtime_source_evidence": {
"controller": {
"finding_count": 0,
"findings": [],
"git_blob_oid": "9c68be36e0b6a18260e3099e3d7b0dcab6d814aa",
"group_gid": 0,
"mode": "0o700",
"mtime_ns": 1785043975531298047,
"owner_uid": 0,
"package_owner": "UNPACKAGED",
"referencing_systemd_units": [
"aios-autonomous-release-authorization-controller.service"
],
"resolved_path": "/usr/libexec/aios-autonomous-release-authorization/controller.py",
"secret_content_returned": false,
"secret_scan": "PASS",
"sha256": "39b532c3058c4ae49ed691d7c66c3b7745a25111fa61039f388c8335fd262c50",
"size": 24204,
"utf8_python": true
},
"isolated_writer_api": {
"canonical_source_path": "NOT_ESTABLISHED",
"runtime_module_status": "ABSENT"
},
"observed_at": "2026-07-28T05:53:01.253909Z",
"router": {
"finding_count": 0,
"findings": [],
"git_blob_oid": "ee0595ca61a0598f8cb3dc10865a255e21679b2a",
"group_gid": 0,
"mode": "0o644",
"mtime_ns": 1785042222580725999,
"owner_uid": 0,
"package_owner": "UNPACKAGED",
"referencing_systemd_units": [
"aios-chatgpt-autonomous-release-route.service"
],
"resolved_path": "/usr/libexec/aios-chatgpt-action-task-router-continuous-20260726/action_task_router.py",
"secret_content_returned": false,
"secret_scan": "PASS",
"sha256": "738fb7035a6b792115d6467b4d1e4ffd47a8c5d5646f7032ebc68ea587cbd554",
"size": 25952,
"utf8_python": true
}
},
"runtime_source_read_projection_evidence_sha256": "23f03d9c6abe6f11e1acda5210b8708696e3b77caa0083b6bfaef30a44b2a35f",
"schema": "aios.gitea-native-approval/v1",
"task_id": "AIOS-INTEGRATION-REFRESH-PROVISIONER-IMPLEMENTATION-20260726",
"writer_audience": "aios-integration-refresh-provisioner-development-writer"
}
@@ -1,40 +0,0 @@
[Unit]
Description=AIOS Codex Review/Test Worker
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=aiman
Group=gitops
WorkingDirectory=/usr/libexec/aios-codex-review-test-worker/current
Environment=AIOS_CODEX_WORKER_MODE=shadow
Environment=AIOS_TASK_PLANE_EXECUTION_ENABLED=false
Environment=PYTHONDONTWRITEBYTECODE=1
ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test
Restart=on-failure
RestartSec=2
NoNewPrivileges=true
PrivateTmp=true
PrivateDevices=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
LockPersonality=true
RestrictSUIDSGID=true
RestrictRealtime=true
MemoryDenyWriteExecute=true
RuntimeDirectory=aios-codex-review-test-worker
StateDirectory=aios-codex-review-test-worker
CacheDirectory=aios-codex-review-test-worker
ReadOnlyPaths=/data/aios-gitops/repo.git
ReadOnlyPaths=/usr/libexec/aios-codex-review-test-worker
ReadWritePaths=/run/aios-codex-review-test-worker
ReadWritePaths=/var/lib/aios-codex-review-test-worker
ReadWritePaths=/var/cache/aios-codex-review-test-worker
UMask=0077
[Install]
WantedBy=multi-user.target
@@ -0,0 +1,24 @@
[Unit]
Description=AIOS root task credential broker (%i)
ConditionPathExists=/var/lib/aios-gitops/runtime/task-status-merge/%i/grant.json
[Service]
Type=oneshot
User=root
Group=root
LoadCredentialEncrypted=audit-key:/run/aios-task-credential-broker/%i-audit.cred
ExecStart=/usr/bin/python3 -m aios_single_owner_governance.task_credential_broker --grant /var/lib/aios-gitops/runtime/task-status-merge/%i/grant.json --grant-signature /var/lib/aios-gitops/runtime/task-status-merge/%i/grant.sig --allowed-signers /etc/aios-gitops/task-status-merge/allowed_signers --audit-key %d/audit-key --audit-dir /var/lib/aios-gitops/runtime/task-status-merge/%i/audit --request /var/lib/aios-gitops/runtime/task-status-merge/%i/credential-request.json
Environment=AIOS_GITOPS_WRITES_ENABLED=false
NoNewPrivileges=false
PrivateTmp=true
PrivateDevices=true
ProtectSystem=strict
ProtectHome=true
ReadOnlyPaths=/data/aios-gitops/runtime/bin/gitea /data/aios-gitops/runtime/gitea-bin/custom/conf/app.ini /var/lib/aios-gitops/runtime/task-status-merge/%i/grant.json /var/lib/aios-gitops/runtime/task-status-merge/%i/grant.sig /var/lib/aios-gitops/runtime/task-status-merge/%i/credential-request.json /etc/aios-gitops/task-status-merge/allowed_signers
ReadWritePaths=/data/aios-gitops/runtime/gitea-bin/data/gitea.db /run/aios-task-credential-broker /var/lib/aios-gitops/runtime/task-status-merge/%i/audit
RestrictAddressFamilies=AF_UNIX AF_INET
IPAddressDeny=any
IPAddressAllow=localhost
LockPersonality=true
MemoryDenyWriteExecute=true
RestrictSUIDSGID=true
@@ -0,0 +1,23 @@
[Unit]
Description=AIOS task credential expiry and completion sweeper
After=aios-gitea.service
Requires=aios-gitea.service
[Service]
Type=oneshot
User=root
Group=root
ExecStart=/usr/bin/python3 -m aios_single_owner_governance.task_credential_expiry_sweeper --runtime-root /var/lib/aios-gitops/runtime/task-status-merge --allowed-signers /etc/aios-gitops/task-status-merge/allowed_signers
Environment=AIOS_GITOPS_WRITES_ENABLED=false
PrivateTmp=true
PrivateDevices=true
ProtectSystem=strict
ProtectHome=true
ReadOnlyPaths=/var/lib/aios-gitops/runtime/task-status-merge /etc/aios-gitops/task-status-merge/allowed_signers
ReadWritePaths=/data/aios-gitops/runtime/gitea-bin/data/gitea.db /run/aios-task-credential-broker /var/lib/aios-gitops/runtime/task-status-merge
RestrictAddressFamilies=AF_UNIX AF_INET
IPAddressDeny=any
IPAddressAllow=localhost
LockPersonality=true
MemoryDenyWriteExecute=true
RestrictSUIDSGID=true
@@ -0,0 +1,12 @@
[Unit]
Description=Run AIOS task credential expiry sweeper every minute
[Timer]
OnBootSec=1min
OnUnitActiveSec=1min
AccuracySec=5s
Persistent=true
Unit=aios-task-credential-expiry-sweeper.service
[Install]
WantedBy=timers.target
@@ -0,0 +1,26 @@
[Unit]
Description=AIOS task-scoped Gitea fast-forward-only merge broker (%i)
After=network.target aios-gitea.service aios-task-status-broker@%i.service
Requires=aios-gitea.service aios-task-status-broker@%i.service
[Service]
Type=oneshot
User=aios-task-merge-bot
Group=aios-task-merge-bot
LoadCredentialEncrypted=gitea-token:/run/aios-task-credential-broker/%i-merge.cred
LoadCredentialEncrypted=audit-key:/run/aios-task-credential-broker/%i-audit.cred
ExecStart=/usr/bin/python3 -m aios_single_owner_governance.task_status_merge_broker --mode merge --grant /var/lib/aios-gitops/runtime/task-status-merge/%i/grant.json --grant-signature /var/lib/aios-gitops/runtime/task-status-merge/%i/grant.sig --allowed-signers /etc/aios-gitops/task-status-merge/allowed_signers --token %d/gitea-token --audit-key %d/audit-key --journal /var/lib/aios-gitops/runtime/task-status-merge/%i/merge-journal/journal.sqlite3
Environment=AIOS_GITOPS_WRITES_ENABLED=false
NoNewPrivileges=true
PrivateTmp=true
PrivateDevices=true
ProtectSystem=strict
ProtectHome=true
RestrictAddressFamilies=AF_UNIX AF_INET
ReadOnlyPaths=/var/lib/aios-gitops/runtime/task-status-merge/%i /etc/aios-gitops/task-status-merge/allowed_signers
ReadWritePaths=/var/lib/aios-gitops/runtime/task-status-merge/%i/merge-journal
IPAddressDeny=any
IPAddressAllow=localhost
LockPersonality=true
MemoryDenyWriteExecute=true
RestrictSUIDSGID=true
@@ -0,0 +1,26 @@
[Unit]
Description=AIOS task-scoped Gitea status broker (%i)
After=network.target aios-gitea.service
Requires=aios-gitea.service
[Service]
Type=oneshot
User=aios-task-status-bot
Group=aios-task-status-bot
LoadCredentialEncrypted=gitea-token:/run/aios-task-credential-broker/%i-status.cred
LoadCredentialEncrypted=audit-key:/run/aios-task-credential-broker/%i-audit.cred
ExecStart=/usr/bin/python3 -m aios_single_owner_governance.task_status_merge_broker --mode status --grant /var/lib/aios-gitops/runtime/task-status-merge/%i/grant.json --grant-signature /var/lib/aios-gitops/runtime/task-status-merge/%i/grant.sig --allowed-signers /etc/aios-gitops/task-status-merge/allowed_signers --evidence /var/lib/aios-gitops/runtime/task-status-merge/%i/status-evidence.json --token %d/gitea-token --audit-key %d/audit-key --journal /var/lib/aios-gitops/runtime/task-status-merge/%i/status-journal/journal.sqlite3
Environment=AIOS_GITOPS_WRITES_ENABLED=false
NoNewPrivileges=true
PrivateTmp=true
PrivateDevices=true
ProtectSystem=strict
ProtectHome=true
RestrictAddressFamilies=AF_UNIX AF_INET
ReadOnlyPaths=/var/lib/aios-gitops/runtime/task-status-merge/%i /etc/aios-gitops/task-status-merge/allowed_signers
ReadWritePaths=/var/lib/aios-gitops/runtime/task-status-merge/%i/status-journal
IPAddressDeny=any
IPAddressAllow=localhost
LockPersonality=true
MemoryDenyWriteExecute=true
RestrictSUIDSGID=true
@@ -0,0 +1,68 @@
# Isolated Writer Exact-Path Policy V1
This policy is an additional, service-owned authorization layer for
`POST /api/commit-file`. It never expands a Token Policy V2 grant.
An atomic write is permitted only when all of the following agree:
1. socket peer, audience, operation, branch, base and exact path in the
Token Policy V2 grant;
2. service audience, repository identity, branch, operation and exact path
in `AIOS_GITOPS_PATH_POLICY_FILE`;
3. lexical path, resolved containment and symlink checks;
4. the configured content-size and content-profile checks;
5. operation digest, expected branch HEAD and durable operation ledger.
Any failed layer returns a fail-closed policy error. Coarse `/api/file` and
`/api/commit` routes remain forbidden.
## File contract
The configured path must be absolute. The parent directory must be
`root:gitops 0750`; the regular, non-symlink file must be
`root:gitops 0640`. JSON must use UTF-8 canonical encoding with sorted keys,
compact separators and one trailing newline. Unknown fields, unsupported
operations or profiles, duplicate paths, oversized policies and
group/world-writable files are rejected during Writer startup.
Example:
```json
{"allowed_branch":"patch/codex-review-test-worker-20260724","allowed_operations":{"commit_file.atomic":{"content_profile":"systemd-codex-review-worker-v1","exact_paths":["deploy/systemd/aios-codex-review-test-worker.service"],"max_content_bytes":32768}},"audience":"aios-codex-review-worker-writer.service","policy_id":"codex-review-worker-path-policy-v1","repository_identity":"aios/aios","schema_version":1}
```
The SHA-256 of the canonical policy is exposed in the isolated runtime
status and written to the operation audit record. The request body cannot
select or override the policy file.
## Content profile
`systemd-codex-review-worker-v1` is an exact, fail-closed unit grammar. The
only sections are `[Unit]`, `[Service]` and `[Install]`. Each section has a
directive allowlist; every single-value directive and every repeated
`Environment`, `ReadOnlyPaths` and `ReadWritePaths` entry must match the
governed Shadow unit contract exactly.
The profile fixes the Python module
`task_plane.workers.codex_review_test`, `User=aiman`, `Group=gitops`,
the controlled `/usr/libexec/aios-codex-review-test-worker/current`
working directory, all hardening switches and the three permitted
environment variables. It grants read access only to the authoritative
bare repository and the versioned worker artifact, and write access only
to the worker runtime, state and cache directories.
Unknown sections or directives are rejected, including lifecycle hooks,
credential injection, environment imports, root images, bind mounts,
capability expansion, devices, sockets and top-level writable paths. The
parser also rejects duplicate sections, duplicate single-value directives,
empty resets, continuation lines, CRLF, NUL, non-UTF-8 surrogate content,
overlong lines and Unicode lookalike directive names. It does not use
`ConfigParser(strict=False)` or silently merge repeated values.
Production credentials, if later authorized, must be supplied by a
separately governed deployment drop-in. They are not permitted in the
source unit or this content profile.
Policy changes require a separate maintenance branch and Owner-reviewed
ordinary merge commit. A task-scoped Writer must not edit its own policy
file.
+44
View File
@@ -51,6 +51,31 @@ components:
path: {type: string, example: docs/gitops/chatgpt-change.md}
content: {type: string}
message: {type: string}
AtomicFileCommitRequest:
type: object
additionalProperties: false
required: [branch, path, content, message, expected_head_oid, idempotency_key]
properties:
branch:
type: string
pattern: '^patch/[A-Za-z0-9._/-]+$'
path:
type: string
minLength: 1
maxLength: 512
content:
type: string
maxLength: 1048576
message:
type: string
minLength: 1
maxLength: 200
expected_head_oid:
type: string
pattern: '^[0-9a-f]{40}$'
idempotency_key:
type: string
pattern: '^[A-Za-z0-9][A-Za-z0-9._:-]{7,127}$'
CommitRequest:
type: object
properties:
@@ -428,6 +453,25 @@ paths:
schema: {$ref: '#/components/schemas/FileCommitRequest'}
responses: {'200': {description: File committed}, '400': {description: Secret rejected or invalid path}, '401': {description: Unauthorized}}
x-openai-isConsequential: true
/api/commit-file:
post:
operationId: commitFileAtomic
summary: Atomically write one allowlisted file, commit, push, and verify using Token Policy V2
security: [{bearerAuth: []}]
requestBody:
required: true
content:
application/json:
schema: {$ref: '#/components/schemas/AtomicFileCommitRequest'}
responses:
'200': {description: Completed or idempotently replayed}
'400': {description: Invalid canonical request}
'401': {description: Missing, invalid, expired, or revoked Token Policy V2 grant}
'403': {description: Audience, source, branch, operation, path, or policy denied}
'409': {description: Idempotency conflict or manual review required}
'413': {description: Request too large}
'503': {description: Push or remote verification unavailable; recoverable}
x-openai-isConsequential: true
/api/commit:
post:
operationId: commitChanges
@@ -1,6 +0,0 @@
{
"schema_version": 1,
"task": "codex-review-test-worker",
"writer_role": "isolated-writer",
"status": "READY"
}
@@ -1,36 +0,0 @@
# Codex Read/Review/Test Worker
This package defines a Shadow-only Task Plane worker for allowlisted code reading,
review, Python tests, compile checks, and Task Plane acceptance. It is not a
production execution authorization.
Safety invariants:
- `max_concurrency=1`, heartbeat 15 seconds, claim lease 120 seconds.
- Task Plane endpoint must be explicit loopback HTTP.
- credentials are read only from a regular, non-symlink `0600` file.
- only low-risk `code.review` and `test.execute` tasks with
`production_side_effects=false` and public/internal data are eligible.
- credential-secret, write, deployment, production, arbitrary shell, network,
path traversal, symlink escape, revision expressions, and secret environment
variables are rejected.
- `ResultEnvelope` is canonical-digest-bound and always has
`trust_level=SHADOW_ATTESTED`, `production_trust=false`.
The committed systemd unit is deliberately non-installable and runs only
`--self-check`. Enabling a real Worker or changing any production execution flag
requires a separate Owner approval and a separately bound artifact.
Artifact build:
```bash
python3 scripts/build_codex_review_worker_artifact.py \
--git-dir /data/aios-gitops/repo.git \
--commit <exact-branch-commit> \
--output <new-empty-output-directory>
```
The temporary canary uses `127.0.0.1:18923`, an isolated state root, an ephemeral
credential file, and a no-`.git` source tree. Remove the unit, token, and state
after acceptance. Do not deploy this package to the existing Task Plane Shadow
runtime as part of build/canary acceptance.
@@ -0,0 +1,75 @@
{
"evidence_type": "TWO_STAGE_OWNER_CAMPAIGN_V2_PHASE_A_CANDIDATE",
"generated_at": "2026-07-30T02:35:51Z",
"execution_status": "PARTIALLY_COMPLETED",
"blocking_layer": "PHASE_A_OWNER_EXACT_HEAD_APPROVAL",
"repository": "aios/aios",
"governance_base_oid": "ebd74398743e36523b593fcc395b73945d4924c5",
"governance_tree_oid": "ad1255a1127204fad1d1208d8f31dc94fa64e6e1",
"authority_main_oid": "875d41c3101093149414292067fd700dc214d4d3",
"schema_seed_commit_oid": "8da47545a507cb798d3d6ab30ff8552a2d0a5ecf",
"schema_seed_tree_oid": "991e68577a469657c1c4996814b6634ce5ed752f",
"candidate_source_commit_oid": "a637a9dbb6e0021cb7dcf0d6b0ca00dfe10dce38",
"candidate_source_tree_oid": "bf6e0c16fcad7515465bec4aefdd2e77b1e9bef0",
"candidate_diff_sha256": "c06d002db06da6cbf16f9c8321f1acbfd431f009b5127a13fd2cb5d63b278867",
"candidate_files_sha256": "5061402d516c0e9413208ce64e2b52f77d224e6eec1f7b07c5b3a10b58df5eaf",
"candidate_file_count": 44,
"schema_document_path": "services/aios-single-owner-governance/task-scoped-governance-bootstrap-v1.schema.json",
"schema_document_sha256": "6ec912a96c8bac5c0d3c0a017abc078cb9567ed54dcb20bb0eadb5926ac54fdd",
"validator_policy_path": "services/aios-single-owner-governance/aios_single_owner_governance/task_scoped_bootstrap.py",
"validator_policy_sha256": "de11123b5cd9ccdad4961f1d5d084a8c4a1b2270ce793652ab9c50bb95694eac",
"two_stage_policy_schema_sha256": "6b4def7c1eef19c01ef73c43252eb0cd1a87c103e1047249a3cfcc75c7922bf6",
"two_stage_release_schema_sha256": "82ee589dc87db6998ddf0779ce264194cadea0deca66088b0797378f6ce89ad3",
"runtime_observer_sha256": "181e632192f1417a98c1efb35631cf80246759080b2e04243576abcdc7da22af",
"journal_anchor_sha256": "18feb0792b95f1060aa696cc60943379695a246984aecf76098838f9ed37426e",
"package_zip_sha256": "668239a549b4a2b2094fe9b5104b84703fe8ed75011fd8ed71ed3958a6dc0706",
"candidate_bundle_sha256": "15711b225b9ef41cca0588d21b2b95d7a95ac155efc27fcb8772c435fcdab147",
"anchor_install_wheel_sha256": "abbf616366eb3467d4e651bb5306e22ae5e931b613df5362a0892935c4a1c0c7",
"tests": {
"two_stage_campaign": {"passed": 67, "failed": 0, "skipped": 0, "collection_errors": 0},
"single_owner_governance": {"passed": 105, "failed": 0, "subtests_passed": 17, "collection_errors": 0},
"task_scoped_bootstrap": {"passed": 15, "failed": 0, "collection_errors": 0},
"compileall": "PASS",
"quarantine_fsck": "PASS",
"systemd_verify": "PASS_WITH_UNRELATED_HOST_WARNINGS"
},
"anchor": {
"service_status": "active",
"anchor_uid": 988,
"runner_uid": 986,
"uids_distinct": true,
"runner_database_write": "DENIED",
"unauthorized_socket_peer": "DENIED",
"runner_registration_action": "ANCHOR_REQUEST_INVALID",
"journal_mode": "WAL",
"synchronous": "FULL",
"foreign_keys": "ON",
"restart_open_reservation": "PASS",
"selftest_open_reservation_cleanup": "ABORTED"
},
"phase_separation": {
"required_owner_decisions": 2,
"phase_a_authorization": "GITEA_EXACT_HEAD_REVIEW",
"phase_b_authorization": "DETACHED_SSH_SIGNATURE",
"phase_a_release_authority": false,
"one_shot_authority": false
},
"isolation": {
"AIOS_GITOPS_WRITES_ENABLED": false,
"publisher_created": false,
"writer_created": false,
"credential_projection_created": false,
"target_branch_created": false,
"tag_created": false,
"registry_modified": false,
"baseline_modified": false,
"production_modified": false
},
"governance": {
"force_push_used": false,
"tag_rewritten": false,
"direct_main_push": false,
"secrets_committed": false,
"owner_approval_respected": true
}
}
@@ -0,0 +1,44 @@
1f4a83cf91e9aacb6f50bc4fb24d4f745a7a31fd1dd7f2d3d3ed0de05e38234f deploy/systemd/aios-campaign-anchor.service
6b2525d31b8544488bce1544deb39a087cc2d830fb1b16fda26cde6ce430dbd2 deploy/systemd/aios-policy-activation-verification@.service
fad52587775ff5f1c5cc16862c5fb1d910bb097c6b3330c00d75db4f7bef0bbd deploy/systemd/aios-policy-campaign-register@.service
de11123b5cd9ccdad4961f1d5d084a8c4a1b2270ce793652ab9c50bb95694eac services/aios-single-owner-governance/aios_single_owner_governance/task_scoped_bootstrap.py
6ec912a96c8bac5c0d3c0a017abc078cb9567ed54dcb20bb0eadb5926ac54fdd services/aios-single-owner-governance/task-scoped-governance-bootstrap-v1.schema.json
5b6d65ae34b2c3bebc1bde8f38c6b0bb73269336d7d4ee5e3416f79c323134d6 services/aios-two-stage-owner-campaign/ANCHOR_REGISTRATION_CONTRACT.md
8ba5278f96447bf4308813b49fcc433d0cc7a5019cd9e78aeb0d8ada5f00d53b services/aios-two-stage-owner-campaign/README.md
7285527358bc8da1d4bc7ff70162dfc3a734086851b734daac89d6f9b330798d services/aios-two-stage-owner-campaign/SECURITY_DELTA_V2.md
89f03fdf156d35807bf39f2f1dbf304c01e7e9ad64399276fb72c68d795eda65 services/aios-two-stage-owner-campaign/STEP_EXECUTOR_CONTRACT.md
7453177223b62509e4854051a75d53f24d8d1f737986f309cc6ae7a2e721459f services/aios-two-stage-owner-campaign/TWO_STAGE_OWNER_INTERACTION_SPEC.md
9308ee245a28a0f0ff623fbfc8e3961204b8e67194bffe536a9c3485ca126ac7 services/aios-two-stage-owner-campaign/examples/allowed_signers.example
9ac7b7fdeb73a99d4f41bf3410ef16f67091d85f9082075287d388e6e5e37eed services/aios-two-stage-owner-campaign/examples/campaign-anchor.env.example
926f0c0cfb7bd6db0ebab6bcb5a0530057b8d38ae1e0b436a69a12b44039462b services/aios-two-stage-owner-campaign/examples/executor-release.example.json
8d46ec9279eb58c03337d41b63de2abdd9eb0d03f98f0806768dcd309d481ee9 services/aios-two-stage-owner-campaign/examples/policy-activation-verification.example.json
b34d8895fe872ef27c62c759449757def698eb05157daff8badd0c86f64ee18c services/aios-two-stage-owner-campaign/examples/release-campaign-manifest.example.json
a2992f493cf0547e1f4acd3fcd9b20e03c912d8b255e196f640d47e291ec9d8e services/aios-two-stage-owner-campaign/examples/runtime-observer-policy.example.json
150c9a8debdcaa4dbb9fd51817ca8710ef805a32f2f96dc5490d0c4f77f2cb6f services/aios-two-stage-owner-campaign/examples/runtime-observer-release.example.json
675b39d13223ad281a4d14a04e739639e470e4e2a2591b85264ba37f840f2b49 services/aios-two-stage-owner-campaign/payload/scripts/generate_diff_chunks.py
5751764275e626c787dad17c2561edd86b2710ae0b3cfeafeec44d98126d9015 services/aios-two-stage-owner-campaign/payload/services/aios-autonomous-control-plane/aios_autonomous_control_plane/lineage_audit.py
2b501bf32a22e1b10c7254d2268d11aa2424aac5756c52441557c25dbaaaa8d5 services/aios-two-stage-owner-campaign/payload/tests/autonomous_control_plane/test_lineage_audit_v3.py
3f118bc7a4f2bdfdd47e2c86112e87f95162dba4d88c1579337bd1d442ec9832 services/aios-two-stage-owner-campaign/pyproject.toml
6b4def7c1eef19c01ef73c43252eb0cd1a87c103e1047249a3cfcc75c7922bf6 services/aios-two-stage-owner-campaign/schemas/governance-policy-activation-verification-v1.schema.json
82ee589dc87db6998ddf0779ce264194cadea0deca66088b0797378f6ce89ad3 services/aios-two-stage-owner-campaign/schemas/task-scoped-release-campaign-v1.schema.json
d04543b5407dcefc0a41af1b8a65ebc2e62f779582ae959449f1ac37b305eecf services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/__init__.py
935a1c1166b0c1ea35a82256345000bf2c73ded718d77773bc27a71ecce28f7d services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/__main__.py
4e317e2fbf912662bfbf57d2f7fe1a9f7fd3d8c00f7ad09602d9e885ee4ef3cc services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/canonical.py
863be28723553e5bf5df90eda49e96edf8417e765da7b41579f050b04336d480 services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/cli.py
dae1e0ed0f841d928a1dd5094c64b1f39b3213301c1da747f45d032a18833c1e services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/errors.py
baf8931566d2c2fb2985d1814b5ded89719bb4b0eba01e94cca9f3690baadeb2 services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/executor.py
18feb0792b95f1060aa696cc60943379695a246984aecf76098838f9ed37426e services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/journal_anchor.py
e24765d3c62f9934a921f099e43a002d349a6c9934438da82040e40238070c58 services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/orchestrator.py
181e632192f1417a98c1efb35631cf80246759080b2e04243576abcdc7da22af services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/runtime_observer.py
3f3ce81490b6f0893665ba296fc23be904ae0e5dcbcd3b602e25feb2571262b0 services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/signature.py
c71d85d5df2ed0e5367de9aacd230f586e77f3b4c11cf52960c84bbdeec43eb7 services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/state_machine.py
75ea8ed1c9b49b1ca3ce452fe229524ebd0ccd802945d3362dd668602ce1f98c services/aios-two-stage-owner-campaign/src/aios_two_stage_campaign/validator.py
b1be7e1ed0fa0e16e041f77200d651cf46f6bb029c89d31f0b286d32c026cb66 services/aios-two-stage-owner-campaign/tests/test_canonical_snapshot.py
0bb956135c90cf71fcb655c4d700c1f71c3442b9e9fddc376959890cdad823de services/aios-two-stage-owner-campaign/tests/test_executor_v2.py
9bb8a9f1c3bd9aaf44db3dd2f5b810eb0cb650da0e5a5f5e2ea50be46f12664d services/aios-two-stage-owner-campaign/tests/test_lineage_payload.py
681c14ddc0be90f94fd3c3d8a6768fe602ec8acd130ed00a8668505d2db57aa2 services/aios-two-stage-owner-campaign/tests/test_orchestrator_v2.py
9edf44fe0129098c31d66f6b6f7ab252879b425e2844969d09e22c3c88e6b77d services/aios-two-stage-owner-campaign/tests/test_runtime_observer.py
204e77c760380f8e29d10fc0afa4227497109d27493245c55a851de6ff69ac86 services/aios-two-stage-owner-campaign/tests/test_signature.py
9bc5dfa237e6bf37ccc90bbc618a807892d323cdd41345717b296838b44cd22a services/aios-two-stage-owner-campaign/tests/test_state_machine.py
a9ef9c11120f480e0cde3ccbf8a816705621506657d8ac10faf7e38fb54bf367 services/aios-two-stage-owner-campaign/tests/test_validator.py
4ec67865474c6c7ebaa7d125490486e8644618b1666cbde597420e4e6fe8f1d4 tests/single_owner_governance/test_task_scoped_bootstrap.py
@@ -1,20 +0,0 @@
{
"schema_version": 1,
"component": "aios-codex-review-test-worker",
"mode": "SHADOW_ONLY",
"production_trust": false,
"production_execution_authorized": false,
"required_acceptance": [
"exact_commit_artifact",
"no_git_canary",
"worker_registration",
"claim_lease_heartbeat",
"progress",
"result_envelope",
"lease_loss_stops_result",
"unsafe_tasks_rejected",
"secret_scan",
"production_side_effects_false"
],
"runtime_result": "GENERATED_OUTSIDE_GIT_DURING_CANARY"
}
@@ -1,138 +0,0 @@
#!/usr/bin/env python3
"""Build a no-.git, exact-commit Codex review worker artifact."""
from __future__ import annotations
import argparse
import hashlib
import json
import os
import re
import shutil
import subprocess
import tarfile
from pathlib import Path
OID_RE = re.compile(r"^[0-9a-f]{40}$")
SECRET_PATTERNS = (
re.compile(rb"Authorization:\s*Bearer\s+[A-Za-z0-9._~+/=-]{16,}", re.I),
re.compile(rb"-----BEGIN (?:RSA |EC |OPENSSH )?PRIVATE KEY-----"),
re.compile(rb"(?:ghp|glpat)_[A-Za-z0-9_-]{20,}", re.I),
)
PACKAGE_PATHS = (
"active-runtime/app/task_plane",
"runtime/agent-os",
"tests/task_plane",
"tests/test_isolated_writer_policy.py",
"scripts/task-plane",
"scripts/run_codex_review_worker_acceptance.py",
"scripts/build_codex_review_worker_artifact.py",
"deploy/systemd/aios-codex-review-test-worker.service",
"docs/task-plane",
"reports/codex-review-worker-acceptance.json",
)
def sha256(path: Path) -> str:
digest = hashlib.sha256()
with path.open("rb") as stream:
for chunk in iter(lambda: stream.read(1024 * 1024), b""):
digest.update(chunk)
return digest.hexdigest()
def atomic_json(path: Path, payload: object) -> None:
temporary = path.with_suffix(path.suffix + ".tmp")
with temporary.open("w", encoding="utf-8", newline="\n") as stream:
json.dump(payload, stream, sort_keys=True, separators=(",", ":"))
stream.write("\n")
stream.flush()
os.fsync(stream.fileno())
os.replace(temporary, path)
def git(git_dir: Path, *args: str) -> str:
return subprocess.run(
["git", f"--git-dir={git_dir}", *args], check=True,
capture_output=True, text=True, timeout=60,
env={"PATH": os.environ.get("PATH", "")},
).stdout.strip()
def build(git_dir: Path, commit: str, output: Path) -> dict[str, str]:
commit = git(git_dir, "rev-parse", f"{commit}^{{commit}}")
if not OID_RE.fullmatch(commit):
raise ValueError("exact commit OID required")
tree_oid = git(git_dir, "rev-parse", f"{commit}^{{tree}}")
for required in PACKAGE_PATHS:
probe = subprocess.run(
["git", f"--git-dir={git_dir}", "cat-file", "-e", f"{commit}:{required}"],
stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL,
)
if probe.returncode != 0:
raise RuntimeError(f"required artifact path missing: {required}")
if output.exists():
raise FileExistsError("output already exists")
output.mkdir(parents=True, mode=0o700)
source_tar = output / "codex-review-worker-source.tar"
subprocess.run(
[
"git", f"--git-dir={git_dir}", "archive", "--format=tar",
f"--output={source_tar}", commit, "--", *PACKAGE_PATHS,
],
check=True, timeout=120, env={"PATH": os.environ.get("PATH", "")},
)
source = output / "source"
source.mkdir(mode=0o700)
with tarfile.open(source_tar, "r") as archive:
archive.extractall(source, filter="data")
if any(item.name == ".git" for item in source.rglob("*")):
raise RuntimeError("artifact contains Git metadata")
findings = []
for item in sorted(path for path in source.rglob("*") if path.is_file() and path.stat().st_size < 5_000_000):
data = item.read_bytes()
if any(pattern.search(data) for pattern in SECRET_PATTERNS):
findings.append(item.relative_to(source).as_posix())
if findings:
raise RuntimeError("secret scan failed")
tracked = git(
git_dir, "ls-tree", "-r", "--name-only", commit, "--", *PACKAGE_PATHS
).splitlines()
files = [
{"path": name, "sha256": sha256(source / name), "size": (source / name).stat().st_size}
for name in tracked if (source / name).is_file()
]
manifest = {"schema_version": 1, "commit": commit, "tree_oid": tree_oid, "files": files}
atomic_json(output / "manifest.json", manifest)
shutil.copyfile(source_tar, output / "rollback-source.tar")
unit = source / "deploy/systemd/aios-codex-review-test-worker.service"
closure = {
"schema_version": 1,
"commit": commit,
"tree_oid": tree_oid,
"artifact_sha256": sha256(source_tar),
"manifest_sha256": sha256(output / "manifest.json"),
"rollback_artifact_sha256": sha256(output / "rollback-source.tar"),
"systemd_unit_sha256": sha256(unit),
"no_git": True,
"secret_scan": "PASS",
}
atomic_json(output / "package-closure.json", closure)
closure["package_closure_sha256"] = sha256(output / "package-closure.json")
with (output / "checksums.sha256").open("w", encoding="utf-8", newline="\n") as stream:
for item in sorted(path for path in output.iterdir() if path.is_file() and path.name != "checksums.sha256"):
stream.write(f"{sha256(item)} {item.name}\n")
return closure
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--git-dir", required=True, type=Path)
parser.add_argument("--commit", required=True)
parser.add_argument("--output", required=True, type=Path)
args = parser.parse_args()
print(json.dumps(build(args.git_dir.resolve(), args.commit, args.output.resolve()), sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -1,159 +0,0 @@
#!/usr/bin/env python3
"""Run or serve an isolated Codex Worker Shadow canary."""
from __future__ import annotations
import argparse
import hashlib
import hmac
import json
import os
import stat
import sys
import urllib.request
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
sys.path.insert(0, str(ROOT / "active-runtime"))
from app.task_plane.api import TaskPlaneService, run_server
from app.task_plane.policy import IdentityVerifier, PolicyEngine, ReadonlyWorkerProfile
from app.task_plane.store import TaskPlaneStore
from app.task_plane.workers.codex_review_test import (
CodexReviewTaskPolicy,
CodexReviewWorker,
READONLY_CAPABILITIES,
)
from app.task_plane.workers.task_client import CredentialSource, StageAClientConfig, TaskPlaneClient
IDENTITY = "spiffe://aios/agent/codex/review-test-canary"
WORKER_ID = "codex-review-test-canary"
def _token(path: Path) -> str:
info = path.lstat()
if path.is_symlink() or not stat.S_ISREG(info.st_mode) or stat.S_IMODE(info.st_mode) != 0o600:
raise SystemExit("canary credential reference rejected")
value = path.read_text(encoding="utf-8").strip()
if len(value.encode("utf-8")) < 32:
raise SystemExit("canary credential unavailable")
return value
def serve(host: str, port: int, state_root: Path, token_file: Path) -> None:
if host not in {"127.0.0.1", "::1"}:
raise SystemExit("canary must bind loopback")
token = _token(token_file)
profile = ReadonlyWorkerProfile(
worker_id=WORKER_ID, identity=IDENTITY,
capabilities=frozenset(READONLY_CAPABILITIES),
)
policy = PolicyEngine(
identity_verifier=IdentityVerifier({IDENTITY}),
execution_enabled=False,
readonly_worker_execution_enabled=True,
readonly_worker_profiles=[profile],
identity_capabilities={
IDENTITY: {"task.creator", "task.read", "task.audit", "task.claim", "worker.self_register"}
},
)
state_root.mkdir(mode=0o700, parents=True, exist_ok=True)
store = TaskPlaneStore(str(state_root / "task-plane.sqlite3"), high_assurance=True)
service = TaskPlaneService(store, policy=policy)
run_server(host, port, service, authenticator=lambda candidate: IDENTITY if hmac.compare_digest(candidate, token) else None)
def _post(base_url: str, token: str, path: str, payload: dict, key: str | None = None) -> dict:
body = json.dumps(payload, sort_keys=True, separators=(",", ":")).encode("utf-8")
headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"}
if key:
headers["Idempotency-Key"] = key
request = urllib.request.Request(base_url + path, data=body, headers=headers, method="POST")
with urllib.request.urlopen(request, timeout=15) as response:
return json.loads(response.read().decode("utf-8"))
def run(base_url: str, token_file: Path, source_commit: str, report: Path) -> dict:
token = _token(token_file)
task_id = "CODEX-CANARY-" + source_commit[:12]
task = {
"task_id": task_id, "task_type": "code.review", "risk": "low",
"required_capabilities": ["code.read"],
"metadata": {"production_side_effects": False},
"data_classification": "internal", "network_policy": "deny",
"allowed_input_paths": ["active-runtime/app/task_plane"],
"allowed_output_paths": ["reports/canary.json"],
}
_post(base_url, token, "/tasks", task, "codex-canary-create-" + source_commit)
client = TaskPlaneClient(StageAClientConfig(base_url), token)
progress = []
def executor(_task, emit):
emit(25, "CLAIMED")
progress.append(25)
emit(100, "VERIFIED")
progress.append(100)
return "shadow canary completed", [{"kind": "summary", "status": "PASS"}], [{"kind": "test", "sha256": hashlib.sha256(source_commit.encode()).hexdigest()}]
worker = CodexReviewWorker(
client, CodexReviewTaskPolicy(WORKER_ID, IDENTITY), source_commit
)
completed_task = worker.run_once(executor)
task_after = client.get_task(task_id)
unsafe_rejected = 0
for unsafe in (
{"risk": "high", "task_type": "code.review", "metadata": {"production_side_effects": False}},
{"risk": "low", "task_type": "code.review", "metadata": {"production_side_effects": True}},
{"risk": "low", "task_type": "code.review", "metadata": {"production_side_effects": False}, "data_classification": "credential-secret"},
{"risk": "low", "task_type": "code.review", "metadata": {"production_side_effects": False}, "required_capabilities": ["code.write"]},
):
try:
worker.policy.assert_shadow_only_task(unsafe)
except Exception:
unsafe_rejected += 1
checks = {
"worker_registration": "PASS",
"task_claim": "PASS" if completed_task == task_id else "FAIL",
"heartbeat": "PASS",
"progress": "PASS" if progress == [25, 100] else "FAIL",
"result_envelope": "PASS" if task_after.get("status") == "COMPLETED" else "FAIL",
"unsafe_task_rejections": "PASS" if unsafe_rejected == 4 else "FAIL",
"network_endpoint_loopback": "PASS",
"production_side_effects": False,
"git_write_count": 0,
"tag_write_count": 0,
"baseline_write_count": 0,
"registry_write_count": 0,
"deployment_count": 0,
}
result = {
"schema_version": 1, "source_commit": source_commit,
"task_id": task_id, "worker_id": WORKER_ID, "checks": checks,
"passed": not any(value == "FAIL" for value in checks.values()),
}
encoded = (json.dumps(result, sort_keys=True, separators=(",", ":")) + "\n").encode("utf-8")
report.write_bytes(encoded)
result["report_sha256"] = hashlib.sha256(encoded).hexdigest()
return result
def main() -> int:
parser = argparse.ArgumentParser()
parser.add_argument("--serve-canary", action="store_true")
parser.add_argument("--host", default="127.0.0.1")
parser.add_argument("--port", type=int, default=18923)
parser.add_argument("--state-root", type=Path)
parser.add_argument("--token-file", required=True, type=Path)
parser.add_argument("--source-commit")
parser.add_argument("--report", type=Path)
args = parser.parse_args()
if args.serve_canary:
serve(args.host, args.port, args.state_root, args.token_file)
return 0
if not args.source_commit or args.report is None:
raise SystemExit("--source-commit and --report are required")
print(json.dumps(run(f"http://{args.host}:{args.port}", args.token_file, args.source_commit, args.report), sort_keys=True))
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,237 @@
from __future__ import annotations
import argparse
import hashlib
import hmac
import json
import os
from pathlib import Path
import sqlite3
import subprocess
from datetime import datetime, timezone
import urllib.error
import urllib.request
from .task_status_merge_broker import ContractDenied, TaskGrant, canonical, load_signed_task_grant, read_runtime_secret
GITEA_BIN = Path("/data/aios-gitops/runtime/bin/gitea")
GITEA_CONFIG = Path("/data/aios-gitops/runtime/gitea-bin/custom/conf/app.ini")
GITEA_DB = Path("/data/aios-gitops/runtime/gitea-bin/data/gitea.db")
RUNUSER = Path("/usr/sbin/runuser")
SYSTEMD_CREDS = Path("/usr/bin/systemd-creds")
GIT = Path("/usr/bin/git")
GITEA_REPOSITORY = Path("/data/aios-gitops/runtime/gitea-bin/data/repositories/aios/aios.git")
def _git(*arguments: str, input_bytes: bytes | None = None) -> bytes:
return subprocess.run(
[str(GIT), f"--git-dir={GITEA_REPOSITORY}", *arguments], input=input_bytes,
check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE,
).stdout
def _verify_local_governance_binding(grant: TaskGrant) -> None:
"""Verify the exact open PR and latest Owner review without issuing a token."""
connection = sqlite3.connect(f"file:{GITEA_DB}?mode=ro", uri=True)
connection.row_factory = sqlite3.Row
try:
pr = connection.execute(
"SELECT pr.head_branch,pr.base_branch,pr.merge_base,pr.has_merged,i.is_closed "
"FROM pull_request pr JOIN issue i ON i.id=pr.issue_id JOIN repository repo ON repo.id=i.repo_id "
"WHERE repo.owner_name='aios' AND repo.lower_name='aios' AND pr.[index]=?",
(grant.raw["pr_number"],),
).fetchone()
review = connection.execute(
"SELECT r.type,r.commit_id,r.official,r.stale,r.dismissed,r.created_unix,u.id,u.lower_name "
"FROM review r JOIN user u ON u.id=r.reviewer_id JOIN issue i ON i.id=r.issue_id "
"JOIN repository repo ON repo.id=i.repo_id "
"WHERE repo.owner_name='aios' AND repo.lower_name='aios' AND i.[index]=? "
"AND u.id=2 AND u.lower_name='owner' ORDER BY r.id DESC LIMIT 1",
(grant.raw["pr_number"],),
).fetchone()
finally:
connection.close()
if pr is None or pr["base_branch"] != "governance/approvals" or pr["merge_base"] != grant.raw["base_oid"] or pr["has_merged"] != 0 or pr["is_closed"] != 0:
raise ContractDenied("LOCAL_PR_BINDING_INVALID")
head = _git("rev-parse", f"refs/heads/{pr['head_branch']}").decode().strip()
base = _git("rev-parse", "refs/heads/governance/approvals").decode().strip()
if head != grant.raw["target_commit"] or base != grant.raw["base_oid"]:
raise ContractDenied("LOCAL_REF_BINDING_INVALID")
if review is None or review["type"] != 1 or review["commit_id"] != head or review["official"] != 1 or review["stale"] != 0 or review["dismissed"] != 0:
raise ContractDenied("LOCAL_OWNER_APPROVAL_MISSING")
submitted = datetime.fromtimestamp(review["created_unix"], tz=timezone.utc)
if submitted < grant.issued_at or submitted >= grant.expires_at:
raise ContractDenied("LOCAL_OWNER_APPROVAL_EXPIRED")
tree = _git("show", "-s", "--format=%T", head).decode().strip()
if tree != grant.raw["approved_tree_oid"]:
raise ContractDenied("APPROVED_TREE_MISMATCH")
entry = _git("ls-tree", head, "--", grant.raw["manifest_path"]).decode().strip().split()
if len(entry) < 3 or entry[1] != "blob" or entry[2] != grant.raw["manifest_blob_oid"]:
raise ContractDenied("MANIFEST_BLOB_BINDING_INVALID")
manifest = _git("cat-file", "blob", grant.raw["manifest_blob_oid"])
if hashlib.sha256(manifest).hexdigest() != grant.raw["manifest_sha256"]:
raise ContractDenied("MANIFEST_SHA256_MISMATCH")
def _safe_absolute(path: Path, expected_parent: Path) -> None:
if not path.is_absolute() or path.is_symlink() or path.parent != expected_parent:
raise ContractDenied("CREDENTIAL_PATH_UNSAFE")
class TaskCredentialBroker:
def __init__(self, grant: TaskGrant, audit_dir: Path, audit_key: bytes):
self.grant = grant
self.audit_key = bytes(audit_key)
if not self.audit_key:
raise ContractDenied("CREDENTIAL_AUDIT_KEY_EMPTY")
self.audit_dir = Path(audit_dir)
if not self.audit_dir.is_absolute() or self.audit_dir.is_symlink():
raise ContractDenied("AUDIT_DIR_UNSAFE")
def provision(self, *, identity: str, token_name: str, encrypted_path: Path) -> dict:
if os.geteuid() != 0:
raise ContractDenied("ROOT_BROKER_REQUIRED")
expected = self.grant.raw["status_identity"] if token_name.endswith("-status") else self.grant.raw["merge_identity"]
if identity != expected or identity not in {"codex", "gpt"}:
raise ContractDenied("IDENTITY_BINDING_INVALID")
prefix = f"pr{self.grant.raw['pr_number']}-{self.grant.raw['target_commit'][:12]}"
if token_name not in {f"{prefix}-status", f"{prefix}-merge"}:
raise ContractDenied("TOKEN_NAME_INVALID")
_safe_absolute(encrypted_path, Path("/run/aios-task-credential-broker"))
if encrypted_path.exists():
raise ContractDenied("CREDENTIAL_PATH_EXISTS")
_verify_local_governance_binding(self.grant)
command = [str(RUNUSER), "-u", "aiman", "--", str(GITEA_BIN), "admin", "user", "generate-access-token", "--config", str(GITEA_CONFIG), "--username", identity, "--token-name", token_name, "--scopes", "write:repository", "--raw"]
issued = subprocess.run(command, check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.strip()
if len(issued) < 32 or b"\n" in issued or b"\x00" in issued:
raise ContractDenied("ISSUED_TOKEN_INVALID")
subprocess.run([str(SYSTEMD_CREDS), "encrypt", "-", str(encrypted_path)], input=issued, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
os.chmod(encrypted_path, 0o400)
connection = sqlite3.connect(f"file:{GITEA_DB}?mode=ro", uri=True)
try:
row = connection.execute("SELECT t.id,u.id FROM access_token t JOIN user u ON u.id=t.uid WHERE u.lower_name=? AND t.name=? AND t.scope='write:repository'", (identity, token_name)).fetchone()
finally:
connection.close()
if row is None:
raise ContractDenied("TOKEN_DATABASE_BINDING_MISSING")
receipt = {"status": "PASS", "operation": "credential_provision", "identity": identity, "token_name": token_name, "token_id": int(row[0]), "token_uid": int(row[1]), "grant_sha256": self.grant.digest, "credential_ref": f"systemd-credential-encrypted://{encrypted_path.name}"}
return self._audit(receipt)
def revoke(self, *, receipt: dict, encrypted_path: Path) -> dict:
if os.geteuid() != 0:
raise ContractDenied("ROOT_BROKER_REQUIRED")
_safe_absolute(encrypted_path, Path("/run/aios-task-credential-broker"))
self.validate_provision_receipt(receipt, encrypted_path)
decrypted = subprocess.run([str(SYSTEMD_CREDS), "decrypt", str(encrypted_path), "-"], check=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).stdout.strip()
if len(decrypted) < 32 or b"\n" in decrypted or b"\x00" in decrypted:
raise ContractDenied("PROJECTED_TOKEN_INVALID")
token_header = {"Authorization": "token " + decrypted.decode("utf-8")}
preflight = urllib.request.Request("http://127.0.0.1:3000/api/v1/repos/aios/aios", headers=token_header)
try:
with urllib.request.urlopen(preflight, timeout=10) as response:
if response.status != 200:
raise ContractDenied("TOKEN_PREFLIGHT_STATUS_INVALID")
except urllib.error.HTTPError as exc:
raise ContractDenied(f"TOKEN_PREFLIGHT_FAILED:{exc.code}") from exc
connection = sqlite3.connect(GITEA_DB)
try:
connection.execute("BEGIN IMMEDIATE")
cursor = connection.execute(
"DELETE FROM access_token WHERE id=? AND uid=? AND name=? AND scope='write:repository'",
(receipt["token_id"], receipt["token_uid"], receipt["token_name"]),
)
if cursor.rowcount != 1:
raise ContractDenied("TOKEN_REVOCATION_MISMATCH")
connection.commit()
except Exception:
connection.rollback()
raise
finally:
connection.close()
connection = sqlite3.connect(f"file:{GITEA_DB}?mode=ro", uri=True)
try:
remaining = connection.execute("SELECT COUNT(*) FROM access_token WHERE id=?", (receipt["token_id"],)).fetchone()[0]
finally:
connection.close()
if remaining != 0:
raise ContractDenied("TOKEN_REVOCATION_READBACK_MISMATCH")
request = urllib.request.Request("http://127.0.0.1:3000/api/v1/repos/aios/aios", headers=token_header)
try:
urllib.request.urlopen(request, timeout=10)
raise ContractDenied("REVOKED_TOKEN_STILL_ACCEPTED")
except urllib.error.HTTPError as exc:
if exc.code != 401:
raise ContractDenied("REVOCATION_HTTP_STATUS_INVALID") from exc
encrypted_path.unlink(missing_ok=True)
result = {"status": "PASS", "operation": "credential_revoke", "identity": receipt["identity"], "token_name": receipt["token_name"], "token_id": receipt["token_id"], "grant_sha256": self.grant.digest, "token_rows_remaining": 0, "credential_projection_remaining": False, "old_token_http_status": 401}
return self._audit(result)
def validate_provision_receipt(self, receipt: dict, encrypted_path: Path) -> None:
required = {"status", "operation", "identity", "token_name", "token_id", "token_uid", "grant_sha256", "credential_ref", "audit_sha256", "audit_hmac_signature"}
expected_credential_ref = f"systemd-credential-encrypted://{encrypted_path.name}"
unsigned_receipt = {key: value for key, value in receipt.items() if key not in {"audit_sha256", "audit_hmac_signature"}}
expected_name_prefix = f"pr{self.grant.raw['pr_number']}-{self.grant.raw['target_commit'][:12]}"
if (set(receipt) != required or receipt["status"] != "PASS" or receipt["operation"] != "credential_provision"
or receipt["grant_sha256"] != self.grant.digest or receipt["identity"] not in {self.grant.raw["status_identity"], self.grant.raw["merge_identity"]}
or receipt["token_name"] not in {f"{expected_name_prefix}-status", f"{expected_name_prefix}-merge"}
or receipt["credential_ref"] != expected_credential_ref
or hashlib.sha256(canonical(unsigned_receipt)).hexdigest() != receipt["audit_sha256"]
or not hmac.compare_digest(receipt["audit_hmac_signature"], hmac.new(self.audit_key, canonical(unsigned_receipt), hashlib.sha256).hexdigest())):
raise ContractDenied("PROVISION_RECEIPT_INVALID")
def _audit(self, value: dict) -> dict:
raw = canonical(value)
result = dict(value)
result["audit_sha256"] = hashlib.sha256(raw).hexdigest()
result["audit_hmac_signature"] = hmac.new(self.audit_key, raw, hashlib.sha256).hexdigest()
self.audit_dir.mkdir(mode=0o750, parents=True, exist_ok=True)
destination = self.audit_dir / f"{value['operation']}-{value['token_name']}.json"
descriptor = os.open(destination, os.O_WRONLY | os.O_CREAT | os.O_EXCL | getattr(os, "O_NOFOLLOW", 0), 0o640)
try:
os.write(descriptor, canonical(result) + b"\n")
os.fsync(descriptor)
finally:
os.close(descriptor)
return result
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(prog="aios-task-credential-broker")
parser.add_argument("--grant", required=True, type=Path)
parser.add_argument("--audit-dir", required=True, type=Path)
parser.add_argument("--operation", choices=("provision", "revoke"))
parser.add_argument("--identity")
parser.add_argument("--token-name")
parser.add_argument("--encrypted-path", type=Path)
parser.add_argument("--receipt", type=Path)
parser.add_argument("--request", type=Path)
parser.add_argument("--grant-signature", required=True, type=Path)
parser.add_argument("--allowed-signers", required=True, type=Path)
parser.add_argument("--audit-key", required=True, type=Path)
args = parser.parse_args(argv)
grant = load_signed_task_grant(args.grant, args.grant_signature, args.allowed_signers)
broker = TaskCredentialBroker(grant, args.audit_dir, read_runtime_secret(args.audit_key))
if args.request is not None:
request = json.loads(args.request.read_text(encoding="utf-8"))
if not isinstance(request, dict) or set(request) not in ({"operation", "identity", "token_name", "encrypted_path"}, {"operation", "identity", "token_name", "encrypted_path", "receipt"}):
raise ContractDenied("CREDENTIAL_REQUEST_INVALID")
args.operation = request["operation"]
args.identity = request["identity"]
args.token_name = request["token_name"]
args.encrypted_path = Path(request["encrypted_path"])
args.receipt = Path(request["receipt"]) if "receipt" in request else None
if args.operation is None or args.identity is None or args.token_name is None or args.encrypted_path is None:
raise ContractDenied("CREDENTIAL_REQUEST_INCOMPLETE")
if args.operation == "provision":
result = broker.provision(identity=args.identity, token_name=args.token_name, encrypted_path=args.encrypted_path)
else:
if args.receipt is None:
raise ContractDenied("RECEIPT_REQUIRED")
result = broker.revoke(receipt=json.loads(args.receipt.read_text(encoding="utf-8")), encrypted_path=args.encrypted_path)
print(json.dumps(result, sort_keys=True, separators=(",", ":")))
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,94 @@
from __future__ import annotations
import argparse
from datetime import datetime, timezone
import json
import os
from pathlib import Path
import sqlite3
import subprocess
from .task_credential_broker import SYSTEMD_CREDS, TaskCredentialBroker
from .task_status_merge_broker import ContractDenied, load_signed_task_grant
RUNTIME_ROOT = Path("/var/lib/aios-gitops/runtime/task-status-merge")
CREDENTIAL_ROOT = Path("/run/aios-task-credential-broker")
def _operation_complete(task_dir: Path, token_name: str) -> bool:
if token_name.endswith("-status"):
journal, operation = task_dir / "status-journal" / "journal.sqlite3", "statuses"
elif token_name.endswith("-merge"):
journal, operation = task_dir / "merge-journal" / "journal.sqlite3", "merge"
else:
raise ContractDenied("SWEEPER_TOKEN_NAME_INVALID")
if not journal.is_file() or journal.is_symlink():
return False
connection = sqlite3.connect(f"file:{journal}?mode=ro", uri=True)
try:
row = connection.execute("SELECT state FROM quota WHERE operation=?", (operation,)).fetchone()
finally:
connection.close()
return row == ("COMMITTED",)
def sweep(runtime_root: Path, allowed_signers: Path, *, now: datetime | None = None) -> list[dict]:
if os.geteuid() != 0:
raise ContractDenied("ROOT_SWEEPER_REQUIRED")
if runtime_root != RUNTIME_ROOT or runtime_root.is_symlink():
raise ContractDenied("SWEEPER_ROOT_INVALID")
current = now or datetime.now(timezone.utc)
results: list[dict] = []
for task_dir in sorted(runtime_root.iterdir() if runtime_root.exists() else []):
if not task_dir.is_dir() or task_dir.is_symlink():
raise ContractDenied("SWEEPER_TASK_DIR_INVALID")
grant_path, signature_path = task_dir / "grant.json", task_dir / "grant.sig"
if not grant_path.is_file() or not signature_path.is_file():
raise ContractDenied("SWEEPER_GRANT_INCOMPLETE")
grant = load_signed_task_grant(grant_path, signature_path, allowed_signers, now=current, allow_expired=True)
audit_credential = CREDENTIAL_ROOT / f"{task_dir.name}-audit.cred"
if not audit_credential.is_file() or audit_credential.is_symlink():
raise ContractDenied("SWEEPER_TASK_AUDIT_CREDENTIAL_MISSING")
audit_key = subprocess.run(
[str(SYSTEMD_CREDS), "decrypt", str(audit_credential), "-"], check=True,
stdout=subprocess.PIPE, stderr=subprocess.PIPE,
).stdout.strip()
if not audit_key or b"\n" in audit_key or b"\x00" in audit_key:
raise ContractDenied("SWEEPER_TASK_AUDIT_KEY_INVALID")
broker = TaskCredentialBroker(grant, task_dir / "audit", audit_key)
for receipt_path in sorted((task_dir / "audit").glob("credential_provision-*.json")):
if receipt_path.is_symlink():
raise ContractDenied("SWEEPER_RECEIPT_UNSAFE")
receipt = json.loads(receipt_path.read_text(encoding="utf-8"))
token_name = str(receipt.get("token_name") or "")
credential_ref = str(receipt.get("credential_ref") or "")
prefix = "systemd-credential-encrypted://"
if not credential_ref.startswith(prefix):
raise ContractDenied("SWEEPER_CREDENTIAL_REF_INVALID")
encrypted_path = CREDENTIAL_ROOT / credential_ref.removeprefix(prefix)
revoked_receipt = task_dir / "audit" / f"credential_revoke-{token_name}.json"
if revoked_receipt.exists():
if encrypted_path.exists():
raise ContractDenied("SWEEPER_REVOKED_PROJECTION_REAPPEARED")
continue
if current < grant.expires_at and not _operation_complete(task_dir, token_name):
continue
if not encrypted_path.is_file() or encrypted_path.is_symlink():
raise ContractDenied("SWEEPER_CREDENTIAL_PROJECTION_MISSING")
results.append(broker.revoke(receipt=receipt, encrypted_path=encrypted_path))
return results
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(prog="aios-task-credential-expiry-sweeper")
parser.add_argument("--runtime-root", required=True, type=Path)
parser.add_argument("--allowed-signers", required=True, type=Path)
args = parser.parse_args(argv)
result = sweep(args.runtime_root, args.allowed_signers)
print(json.dumps({"status": "PASS", "revoked": result}, sort_keys=True, separators=(",", ":")))
return 0
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,436 @@
from __future__ import annotations
import argparse
from dataclasses import dataclass
from datetime import datetime, timezone
import hashlib
import hmac
import json
import os
from pathlib import Path
import re
import sqlite3
import stat
import subprocess
from typing import Any, Protocol
import urllib.error
import urllib.parse
import urllib.request
ALLOWED_CONTEXTS = frozenset({
"aios/branch-protection",
"aios/evidence-closure",
"aios/secret-scan",
"aios/state-machine",
"aios/validator",
})
ALLOWED_IDENTITIES = frozenset({"codex", "gpt"})
OID = re.compile(r"^[0-9a-f]{40}$")
SHA256 = re.compile(r"^[0-9a-f]{64}$")
SECRET_REF = re.compile(r"^systemd-credential://[A-Za-z0-9_.-]+$")
SUPERSEDED_PR_NUMBER = 36
SUPERSEDED_HEAD_OID = "a8644fc172bd8ebbba17a16e6bf586c93fd1e793"
FIELDS = frozenset({
"schema_id", "schema_version", "repository", "pr_number", "base_oid",
"target_commit", "approved_tree_oid", "manifest_path", "manifest_blob_oid", "manifest_sha256",
"payload_sha256", "status_identity", "merge_identity", "status_contexts",
"status_write_quota", "merge_quota", "merge_method", "branch_push_allowed",
"tag_write_allowed", "main_write_allowed", "registry_write_allowed",
"baseline_write_allowed", "production_write_allowed", "issued_at", "expires_at",
"audit_key_ref", "grant_signer_identity", "grant_signature_namespace",
"status_evidence_sha256", "supersedes_pr_number", "supersedes_head_oid",
"renewal_required",
})
class ContractDenied(RuntimeError):
pass
def canonical(value: Any) -> bytes:
return json.dumps(value, sort_keys=True, separators=(",", ":")).encode()
def _time(value: str) -> datetime:
if not isinstance(value, str) or not value.endswith("Z"):
raise ContractDenied("TIMESTAMP_INVALID")
try:
return datetime.fromisoformat(value.replace("Z", "+00:00"))
except ValueError as exc:
raise ContractDenied("TIMESTAMP_INVALID") from exc
@dataclass(frozen=True)
class TaskGrant:
raw: dict[str, Any]
issued_at: datetime
expires_at: datetime
@classmethod
def from_dict(cls, value: dict[str, Any], *, now: datetime | None = None,
allow_expired: bool = False) -> "TaskGrant":
if not isinstance(value, dict) or set(value) != FIELDS:
raise ContractDenied("GRANT_FIELDS_INVALID")
if value["schema_id"] != "AIOS_TASK_STATUS_MERGE_GRANT" or value["schema_version"] != 1:
raise ContractDenied("GRANT_SCHEMA_INVALID")
if value["repository"] != "aios/aios" or type(value["pr_number"]) is not int or value["pr_number"] <= 0:
raise ContractDenied("REPOSITORY_OR_PR_MISMATCH")
for field in ("base_oid", "target_commit", "approved_tree_oid", "manifest_blob_oid"):
if not isinstance(value[field], str) or not OID.fullmatch(value[field]):
raise ContractDenied("OID_INVALID")
if not isinstance(value["manifest_path"], str) or not re.fullmatch(r"approvals/[A-Za-z0-9._/-]+\.json", value["manifest_path"]) or ".." in value["manifest_path"].split("/"):
raise ContractDenied("MANIFEST_PATH_INVALID")
for field in ("manifest_sha256", "payload_sha256"):
if not isinstance(value[field], str) or not SHA256.fullmatch(value[field]):
raise ContractDenied("SHA256_INVALID")
evidence = value["status_evidence_sha256"]
if not isinstance(evidence, dict) or set(evidence) != ALLOWED_CONTEXTS or any(not isinstance(item, str) or not SHA256.fullmatch(item) for item in evidence.values()):
raise ContractDenied("STATUS_EVIDENCE_BINDING_INVALID")
if value["supersedes_pr_number"] != SUPERSEDED_PR_NUMBER or value["pr_number"] == SUPERSEDED_PR_NUMBER:
raise ContractDenied("RENEWAL_PR_INVALID")
if value["supersedes_head_oid"] != SUPERSEDED_HEAD_OID or value["supersedes_head_oid"] == value["target_commit"] or value["renewal_required"] is not True:
raise ContractDenied("RENEWAL_BINDING_INVALID")
if value["status_identity"] not in ALLOWED_IDENTITIES or value["merge_identity"] not in ALLOWED_IDENTITIES:
raise ContractDenied("IDENTITY_NOT_ALLOWED")
if set(value["status_contexts"]) != ALLOWED_CONTEXTS or len(value["status_contexts"]) != 5:
raise ContractDenied("STATUS_CONTEXTS_INVALID")
if value["status_write_quota"] != 5 or value["merge_quota"] != 1:
raise ContractDenied("QUOTA_INVALID")
if value["merge_method"] != "fast-forward-only":
raise ContractDenied("MERGE_METHOD_INVALID")
denied = (
"branch_push_allowed", "tag_write_allowed", "main_write_allowed",
"registry_write_allowed", "baseline_write_allowed", "production_write_allowed",
)
if any(value[field] is not False for field in denied):
raise ContractDenied("WRITE_SCOPE_EXPANDED")
if not isinstance(value["audit_key_ref"], str) or not SECRET_REF.fullmatch(value["audit_key_ref"]):
raise ContractDenied("AUDIT_KEY_REFERENCE_INVALID")
if value["grant_signer_identity"] != "aios-task-grant-signer" or value["grant_signature_namespace"] != "aios-task-status-merge-grant-v1":
raise ContractDenied("GRANT_SIGNATURE_POLICY_INVALID")
issued, expires = _time(value["issued_at"]), _time(value["expires_at"])
current = now or datetime.now(timezone.utc)
lifetime = (expires - issued).total_seconds()
if lifetime <= 0 or lifetime > 12 * 3600 or (not allow_expired and current >= expires):
raise ContractDenied("GRANT_EXPIRED_OR_LIFETIME_INVALID")
return cls(dict(value), issued, expires)
@property
def digest(self) -> str:
return hashlib.sha256(canonical(self.raw)).hexdigest()
def load_signed_task_grant(grant_path: Path, signature_path: Path, allowed_signers: Path,
*, now: datetime | None = None, allow_expired: bool = False) -> TaskGrant:
for path in (grant_path, signature_path, allowed_signers):
if not path.is_absolute() or path.is_symlink():
raise ContractDenied("GRANT_SIGNATURE_PATH_UNSAFE")
raw = grant_path.read_bytes()
if len(raw) > 1024 * 1024:
raise ContractDenied("GRANT_TOO_LARGE")
try:
value = json.loads(raw)
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
raise ContractDenied("GRANT_JSON_INVALID") from exc
if raw != canonical(value) + b"\n":
raise ContractDenied("GRANT_NOT_CANONICAL")
grant = TaskGrant.from_dict(value, now=now, allow_expired=allow_expired)
command = [
"/usr/bin/ssh-keygen", "-Y", "verify", "-f", str(allowed_signers),
"-I", "aios-task-grant-signer", "-n", "aios-task-status-merge-grant-v1",
"-s", str(signature_path),
]
try:
subprocess.run(command, input=raw, check=True, stdout=subprocess.DEVNULL, stderr=subprocess.PIPE)
except (OSError, subprocess.CalledProcessError) as exc:
raise ContractDenied("GRANT_SIGNATURE_INVALID") from exc
return grant
class API(Protocol):
def get(self, path: str) -> Any: ...
def post(self, path: str, payload: dict[str, Any]) -> Any: ...
def read_runtime_secret(path: Path) -> bytes:
flags = os.O_RDONLY | getattr(os, "O_CLOEXEC", 0) | getattr(os, "O_NOFOLLOW", 0)
descriptor = os.open(path, flags)
try:
metadata = os.fstat(descriptor)
if not stat.S_ISREG(metadata.st_mode) or stat.S_IMODE(metadata.st_mode) & 0o077:
raise ContractDenied("CREDENTIAL_FILE_UNSAFE")
value = os.read(descriptor, 16 * 1024 + 1)
finally:
os.close(descriptor)
if not value or len(value) > 16 * 1024 or b"\x00" in value or b"\n" in value.strip():
raise ContractDenied("CREDENTIAL_CONTENT_INVALID")
return value.strip()
class _NoRedirect(urllib.request.HTTPRedirectHandler):
def redirect_request(self, req, fp, code, msg, headers, newurl):
return None
class GiteaClient:
def __init__(self, token_path: Path, api_base: str = "http://127.0.0.1:3000/api/v1"):
parsed = urllib.parse.urlparse(api_base)
if parsed.scheme != "http" or parsed.hostname != "127.0.0.1" or parsed.path.rstrip("/") != "/api/v1" or parsed.username or parsed.password or parsed.query or parsed.fragment:
raise ContractDenied("GITEA_API_ORIGIN_INVALID")
self.token_path = Path(token_path)
self.api_base = api_base.rstrip("/")
self.opener = urllib.request.build_opener(_NoRedirect)
def _request(self, method: str, path: str, payload: dict[str, Any] | None = None) -> Any:
if not path.startswith("/") or ".." in path.split("/"):
raise ContractDenied("GITEA_API_PATH_INVALID")
token = read_runtime_secret(self.token_path).decode("utf-8")
body = canonical(payload) if payload is not None else None
request = urllib.request.Request(self.api_base + path, data=body, method=method, headers={"Authorization": f"token {token}", "Content-Type": "application/json", "Accept": "application/json"})
try:
with self.opener.open(request, timeout=20) as response:
raw = response.read(2 * 1024 * 1024 + 1)
except (urllib.error.URLError, OSError) as exc:
raise ContractDenied(f"GITEA_API_FAILED:{type(exc).__name__}") from exc
if len(raw) > 2 * 1024 * 1024:
raise ContractDenied("GITEA_API_RESPONSE_TOO_LARGE")
return json.loads(raw.decode("utf-8")) if raw else None
def get(self, path: str) -> Any:
return self._request("GET", path)
def post(self, path: str, payload: dict[str, Any]) -> Any:
return self._request("POST", path, payload)
class QuotaJournal:
def __init__(self, path: Path, grant: TaskGrant):
self.path = Path(path)
self.grant = grant
self.connection = sqlite3.connect(self.path, isolation_level=None)
self.connection.execute("PRAGMA journal_mode=WAL")
self.connection.execute("PRAGMA synchronous=FULL")
self.connection.execute("CREATE TABLE IF NOT EXISTS quota(operation TEXT PRIMARY KEY, state TEXT NOT NULL, effect_sha256 TEXT)")
self.connection.execute("CREATE TABLE IF NOT EXISTS audit(seq INTEGER PRIMARY KEY AUTOINCREMENT, event BLOB NOT NULL, previous_hash TEXT NOT NULL, event_hash TEXT NOT NULL UNIQUE)")
def close(self) -> None:
self.connection.close()
def reserve(self, operation: str) -> str:
limit = {"statuses": 1, "merge": 1}.get(operation)
if limit is None:
raise ContractDenied("OPERATION_INVALID")
self.connection.execute("BEGIN IMMEDIATE")
try:
row = self.connection.execute("SELECT state FROM quota WHERE operation=?", (operation,)).fetchone()
if row and row[0] == "COMMITTED":
raise ContractDenied("STATUS_QUOTA_EXHAUSTED" if operation == "statuses" else "MERGE_QUOTA_EXHAUSTED")
if row and row[0] != "RESERVED":
raise ContractDenied("JOURNAL_STATE_INVALID")
if not row:
self.connection.execute("INSERT INTO quota(operation,state,effect_sha256) VALUES(?,'RESERVED',NULL)", (operation,))
self.connection.execute("COMMIT")
return "RESERVED"
except Exception:
self.connection.execute("ROLLBACK")
raise
def state(self, operation: str) -> str | None:
row = self.connection.execute("SELECT state FROM quota WHERE operation=?", (operation,)).fetchone()
return str(row[0]) if row else None
def commit(self, operation: str, effect: dict[str, Any]) -> None:
digest = hashlib.sha256(canonical(effect)).hexdigest()
self.connection.execute("BEGIN IMMEDIATE")
try:
row = self.connection.execute("SELECT state,effect_sha256 FROM quota WHERE operation=?", (operation,)).fetchone()
if row is None or row[0] not in {"RESERVED", "COMMITTED"}:
raise ContractDenied("RESERVATION_MISSING")
if row[0] == "COMMITTED" and row[1] != digest:
raise ContractDenied("COMMITTED_EFFECT_MISMATCH")
self.connection.execute("UPDATE quota SET state='COMMITTED',effect_sha256=? WHERE operation=?", (digest, operation))
self.connection.execute("COMMIT")
except Exception:
self.connection.execute("ROLLBACK")
raise
def append(self, event: dict[str, Any]) -> str:
row = self.connection.execute("SELECT event_hash FROM audit ORDER BY seq DESC LIMIT 1").fetchone()
previous = row[0] if row else "0" * 64
raw = canonical(event)
digest = hashlib.sha256(previous.encode() + raw).hexdigest()
self.connection.execute("INSERT INTO audit(event,previous_hash,event_hash) VALUES(?,?,?)", (raw, previous, digest))
return digest
def verify_chain(self) -> bool:
previous = "0" * 64
for raw, observed_previous, observed_hash in self.connection.execute("SELECT event,previous_hash,event_hash FROM audit ORDER BY seq"):
if observed_previous != previous or hashlib.sha256(previous.encode() + raw).hexdigest() != observed_hash:
return False
previous = observed_hash
return True
def _latest_statuses(values: Any) -> dict[str, dict[str, Any]]:
if not isinstance(values, list):
raise ContractDenied("STATUS_RESPONSE_INVALID")
latest: dict[str, tuple[tuple[str, int], dict[str, Any]]] = {}
for item in values:
if not isinstance(item, dict) or item.get("context") not in ALLOWED_CONTEXTS:
continue
key = (str(item.get("created_at") or ""), int(item.get("id") or 0))
context = item["context"]
if context not in latest or key > latest[context][0]:
latest[context] = (key, item)
return {context: item for context, (_, item) in latest.items()}
def _verify_owner_binding(api: API, grant: TaskGrant) -> tuple[dict[str, Any], dict[str, Any]]:
pr_number = grant.raw["pr_number"]
head, base = grant.raw["target_commit"], grant.raw["base_oid"]
pr = api.get(f"/repos/aios/aios/pulls/{pr_number}")
reviews = api.get(f"/repos/aios/aios/pulls/{pr_number}/reviews")
if not isinstance(pr, dict) or pr.get("state") != "open" or pr.get("mergeable") is not True or (pr.get("head") or {}).get("sha") != head or (pr.get("base") or {}).get("sha") != base or (pr.get("base") or {}).get("ref") != "governance/approvals":
raise ContractDenied("PR_BINDING_INVALID")
if not isinstance(reviews, list):
raise ContractDenied("REVIEW_RESPONSE_INVALID")
owners = [item for item in reviews if isinstance(item, dict) and (item.get("user") or {}).get("login") == "owner" and (item.get("user") or {}).get("id") == 2]
if not owners:
raise ContractDenied("OWNER_EXACT_HEAD_APPROVAL_MISSING")
latest = max(owners, key=lambda item: int(item.get("id") or -1))
if latest.get("state") != "APPROVED" or latest.get("commit_id") != head or latest.get("official") is not True or latest.get("stale") is not False or latest.get("dismissed") is not False:
raise ContractDenied("OWNER_EXACT_HEAD_APPROVAL_MISSING")
submitted = _time(str(latest.get("submitted_at") or ""))
if submitted < grant.issued_at or submitted >= grant.expires_at:
raise ContractDenied("OWNER_APPROVAL_EXPIRED")
return pr, latest
def _signed_receipt(value: dict[str, Any], key: bytes) -> dict[str, Any]:
if not key:
raise ContractDenied("AUDIT_KEY_EMPTY")
result = dict(value)
result["audit_signature"] = hmac.new(key, canonical(value), hashlib.sha256).hexdigest()
return result
class StatusBroker:
def __init__(self, grant: TaskGrant, journal: QuotaJournal, api: API, audit_key: bytes):
self.grant, self.journal, self.api, self.audit_key = grant, journal, api, audit_key
def publish(self, evidence: list[dict[str, Any]]) -> dict[str, Any]:
if not isinstance(evidence, list) or len(evidence) != 5:
raise ContractDenied("EVIDENCE_SET_INVALID")
mapped = {item.get("context"): item for item in evidence if isinstance(item, dict)}
if set(mapped) != ALLOWED_CONTEXTS or any(set(item) != {"context", "evidence_sha256"} or not SHA256.fullmatch(str(item["evidence_sha256"])) or item["evidence_sha256"] != self.grant.raw["status_evidence_sha256"].get(context) for context, item in mapped.items()):
raise ContractDenied("EVIDENCE_SET_INVALID")
_verify_owner_binding(self.api, self.grant)
self.journal.reserve("statuses")
published = []
head = self.grant.raw["target_commit"]
pr_number = self.grant.raw["pr_number"]
observed_before = self.api.get(f"/repos/aios/aios/commits/{head}/statuses")
already = _latest_statuses(observed_before)
already = {context: item for context, item in already.items()
if item.get("status", item.get("state")) == "success"
and item.get("sha", head) == head
and (item.get("creator") or {}).get("login") == self.grant.raw["status_identity"]
and str(item.get("description") or "").endswith(mapped[context]["evidence_sha256"])}
for context in sorted(ALLOWED_CONTEXTS):
digest = mapped[context]["evidence_sha256"]
if context in already:
published.append({"context": context, "evidence_sha256": digest, "status_id": already[context].get("id"), "reconciled": True})
continue
response = self.api.post(f"/repos/aios/aios/statuses/{head}", {
"state": "success", "context": context,
"description": f"task-scoped PASS evidence_sha256={digest}",
"target_url": f"https://g.cnnetmkt.top/git/aios/aios/pulls/{pr_number}",
})
if not isinstance(response, dict) or response.get("context") != context or response.get("status", response.get("state")) != "success":
raise ContractDenied("STATUS_PUBLICATION_FAILED")
published.append({"context": context, "evidence_sha256": digest, "status_id": response.get("id")})
observed = self.api.get(f"/repos/aios/aios/commits/{head}/statuses")
latest = _latest_statuses(observed)
if set(latest) != ALLOWED_CONTEXTS or any(
item.get("status", item.get("state")) != "success"
or item.get("sha", head) != head
or (item.get("creator") or {}).get("login") != self.grant.raw["status_identity"]
or not str(item.get("description") or "").endswith(mapped[context]["evidence_sha256"])
for context, item in latest.items()
):
raise ContractDenied("STATUS_READBACK_INVALID")
receipt = {"status": "PASS", "operation": "publish_statuses", "grant_sha256": self.grant.digest, "target_commit": head, "published_count": 5, "published": published}
receipt["audit_signature"] = hmac.new(self.audit_key, canonical(receipt), hashlib.sha256).hexdigest()
receipt["audit_chain_hash"] = self.journal.append(receipt)
self.journal.commit("statuses", receipt)
return receipt
class MergeBroker:
def __init__(self, grant: TaskGrant, journal: QuotaJournal, api: API, audit_key: bytes):
self.grant, self.journal, self.api, self.audit_key = grant, journal, api, audit_key
def merge(self) -> dict[str, Any]:
head, base = self.grant.raw["target_commit"], self.grant.raw["base_oid"]
pr_number = self.grant.raw["pr_number"]
pr = self.api.get(f"/repos/aios/aios/pulls/{pr_number}")
if isinstance(pr, dict) and pr.get("merged") is True:
observed_branch = self.api.get("/repos/aios/aios/branches/governance%2Fapprovals")
if pr.get("merge_commit_sha") != head or (observed_branch.get("commit") or {}).get("id") != head or self.journal.state("merge") != "RESERVED":
raise ContractDenied("FAST_FORWARD_RESULT_MISMATCH")
receipt = {"status": "PASS", "operation": "fast_forward_merge", "grant_sha256": self.grant.digest, "pr_number": pr_number, "governance_oid": head, "merge_method": "fast-forward-only", "reconciled": True}
receipt["audit_signature"] = hmac.new(self.audit_key, canonical(receipt), hashlib.sha256).hexdigest()
receipt["audit_chain_hash"] = self.journal.append(receipt)
self.journal.commit("merge", receipt)
return receipt
pr, _ = _verify_owner_binding(self.api, self.grant)
statuses = self.api.get(f"/repos/aios/aios/commits/{head}/statuses")
latest = _latest_statuses(statuses)
if set(latest) != ALLOWED_CONTEXTS or any(item.get("status", item.get("state")) != "success" or item.get("sha", head) != head or (item.get("creator") or {}).get("login") != self.grant.raw["status_identity"] or not str(item.get("description") or "").endswith(self.grant.raw["status_evidence_sha256"][context]) for context, item in latest.items()):
raise ContractDenied("MACHINE_STATUS_INVALID")
self.journal.reserve("merge")
self.api.post(f"/repos/aios/aios/pulls/{pr_number}/merge", {"Do": "fast-forward-only", "head_commit_id": head, "force_merge": False, "delete_branch_after_merge": False})
observed_pr = self.api.get(f"/repos/aios/aios/pulls/{pr_number}")
observed_branch = self.api.get("/repos/aios/aios/branches/governance%2Fapprovals")
if observed_pr.get("merged") is not True or observed_pr.get("merge_commit_sha") != head or (observed_branch.get("commit") or {}).get("id") != head:
raise ContractDenied("FAST_FORWARD_RESULT_MISMATCH")
receipt = {"status": "PASS", "operation": "fast_forward_merge", "grant_sha256": self.grant.digest, "pr_number": pr_number, "governance_oid": head, "merge_method": "fast-forward-only"}
receipt["audit_signature"] = hmac.new(self.audit_key, canonical(receipt), hashlib.sha256).hexdigest()
receipt["audit_chain_hash"] = self.journal.append(receipt)
self.journal.commit("merge", receipt)
return receipt
def main(argv: list[str] | None = None) -> int:
parser = argparse.ArgumentParser(prog="aios-task-status-merge-broker")
parser.add_argument("--mode", required=True, choices=("status", "merge"))
parser.add_argument("--grant", required=True, type=Path)
parser.add_argument("--token", required=True, type=Path)
parser.add_argument("--audit-key", required=True, type=Path)
parser.add_argument("--grant-signature", required=True, type=Path)
parser.add_argument("--allowed-signers", required=True, type=Path)
parser.add_argument("--journal", required=True, type=Path)
parser.add_argument("--evidence", type=Path)
args = parser.parse_args(argv)
grant = load_signed_task_grant(args.grant, args.grant_signature, args.allowed_signers)
journal = QuotaJournal(args.journal, grant)
try:
client = GiteaClient(args.token)
key = read_runtime_secret(args.audit_key)
if args.mode == "status":
if args.evidence is None:
raise ContractDenied("EVIDENCE_REQUIRED")
result = StatusBroker(grant, journal, client, key).publish(json.loads(args.evidence.read_text(encoding="utf-8")))
else:
if args.evidence is not None:
raise ContractDenied("EVIDENCE_FORBIDDEN")
result = MergeBroker(grant, journal, client, key).merge()
print(json.dumps(result, sort_keys=True, separators=(",", ":")))
return 0
finally:
journal.close()
if __name__ == "__main__":
raise SystemExit(main())
@@ -0,0 +1,323 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "TASK_SCOPED_GOVERNANCE_BOOTSTRAP",
"title": "TASK_SCOPED_GOVERNANCE_BOOTSTRAP observed approval envelope",
"description": "Versioned fail-closed validation envelope assembled from an immutable request plus observed Owner, Git, machine-gate, runtime, and mirror evidence.",
"x-schema-version": 1,
"x-schema-status": "CANDIDATE",
"type": "object",
"additionalProperties": false,
"required": [
"document_kind",
"request_id",
"schema_id",
"schema_version",
"request_created_at",
"request_expires_at",
"requester_identity",
"repository_identity",
"approval_plan_path",
"approval_plan_blob_oid",
"approval_plan_sha256",
"schema_document_sha256",
"validator_policy_sha256",
"required_machine_contexts",
"governance_base_ref",
"governance_base_oid",
"request_head_ref",
"request_head_oid",
"code_base_ref",
"code_base_oid",
"candidate_commit_oid",
"candidate_parent_oid",
"candidate_tree_oid",
"candidate_diff_sha256",
"candidate_files_sha256",
"target_ref",
"target_initial_state",
"provision_publisher",
"provision_writer",
"provision_credential_projection",
"publisher_identity",
"writer_identity",
"credential_secret_ref",
"publisher_scope",
"writer_scope",
"credential_scope",
"observed_preapproval_operations",
"allowed_operations",
"allowed_operations_sha256",
"denied_operations",
"maximum_operation_count",
"maximum_pr_count",
"maximum_branch_count",
"maximum_commit_count",
"allowed_paths",
"allowed_paths_sha256",
"approved_at",
"expires_at",
"maximum_lifetime_seconds",
"auto_revoke",
"required_human_approvals",
"allowed_human_approvers",
"approved_by",
"owner_review_id",
"owner_review_commit_oid",
"approval_plan_id",
"approval_audit_event_id",
"production_runtime_anchor_change",
"production_writes_enabled",
"tag_operations",
"registry_operations",
"baseline_operations",
"deployment_operations",
"force_push_allowed",
"tag_rewrite_allowed",
"direct_main_push_allowed"
],
"properties": {
"document_kind": {"const": "ENVELOPE"},
"request_id": {"type": "string", "minLength": 3, "maxLength": 192, "pattern": "^[A-Za-z0-9][A-Za-z0-9_.:-]+$"},
"schema_id": {"const": "TASK_SCOPED_GOVERNANCE_BOOTSTRAP"},
"schema_version": {"const": 1},
"request_created_at": {"type": "string", "format": "date-time", "pattern": "Z$"},
"request_expires_at": {"type": "string", "format": "date-time", "pattern": "Z$"},
"requester_identity": {"$ref": "#/$defs/identity"},
"repository_identity": {"const": "aios/aios"},
"approval_plan_path": {"type": "string", "pattern": "^approvals/governance-bootstrap/[A-Za-z0-9._-]+\\.json$"},
"approval_plan_blob_oid": {"$ref": "#/$defs/oid"},
"approval_plan_sha256": {"$ref": "#/$defs/sha256"},
"schema_document_sha256": {"$ref": "#/$defs/sha256"},
"validator_policy_sha256": {"$ref": "#/$defs/sha256"},
"required_machine_contexts": {
"type": "array",
"minItems": 5,
"maxItems": 5,
"uniqueItems": true,
"items": {"enum": [
"governance/authority-mirror",
"governance/fault-injection",
"governance/runtime-isolation",
"governance/schema-contract",
"governance/validator-security"
]}
},
"governance_base_ref": {"const": "refs/heads/governance/approvals"},
"governance_base_oid": {"$ref": "#/$defs/oid"},
"request_head_ref": {"type": "string", "pattern": "^refs/heads/governance/request/[A-Za-z0-9._/-]+$"},
"request_head_oid": {"$ref": "#/$defs/oid"},
"code_base_ref": {"type": "string", "pattern": "^refs/heads/patch/[A-Za-z0-9._/-]+$"},
"code_base_oid": {"$ref": "#/$defs/oid"},
"candidate_commit_oid": {"$ref": "#/$defs/oid"},
"candidate_parent_oid": {"$ref": "#/$defs/oid"},
"candidate_tree_oid": {"$ref": "#/$defs/oid"},
"candidate_diff_sha256": {"$ref": "#/$defs/sha256"},
"candidate_files_sha256": {"$ref": "#/$defs/sha256"},
"target_ref": {"type": "string", "pattern": "^refs/heads/patch/[A-Za-z0-9._/-]+$"},
"target_initial_state": {"const": "ABSENT"},
"provision_publisher": {"const": true},
"provision_writer": {"const": true},
"provision_credential_projection": {"const": true},
"publisher_identity": {"$ref": "#/$defs/identity"},
"writer_identity": {"$ref": "#/$defs/identity"},
"credential_secret_ref": {"type": "string", "pattern": "^(systemd-credential|secret-ref)://[A-Za-z0-9_.-]+$"},
"publisher_scope": {
"type": "object",
"additionalProperties": false,
"required": ["repository", "local_code_write", "administrator"],
"properties": {
"repository": {"const": "aios/aios"},
"local_code_write": {"const": false},
"administrator": {"const": false}
}
},
"writer_scope": {
"type": "object",
"additionalProperties": false,
"required": ["repository", "remote_credentials", "remote_push", "run_as_root"],
"properties": {
"repository": {"const": "aios/aios"},
"remote_credentials": {"const": false},
"remote_push": {"const": false},
"run_as_root": {"const": false}
}
},
"credential_scope": {
"type": "object",
"additionalProperties": false,
"required": [
"provider", "projection", "audience", "writer_visible",
"runtime_anchor_visible", "expires_with_request", "revocation_required",
"post_revoke_http_status"
],
"properties": {
"provider": {"const": "systemd"},
"projection": {"const": "LoadCredential"},
"audience": {"$ref": "#/$defs/identity"},
"writer_visible": {"const": false},
"runtime_anchor_visible": {"const": false},
"expires_with_request": {"const": true},
"revocation_required": {"const": true},
"post_revoke_http_status": {"const": 401}
}
},
"observed_preapproval_operations": {
"type": "array",
"minItems": 2,
"maxItems": 2,
"uniqueItems": true,
"items": {"enum": [
"create_governance_request_branch",
"create_governance_approval_pr"
]}
},
"allowed_operations": {
"type": "array",
"minItems": 1,
"uniqueItems": true,
"items": {"enum": [
"provision_task_publisher",
"provision_task_writer",
"provision_task_credential_projection",
"create_approved_code_branch",
"push_approved_code_branch",
"read_remote_refs",
"revoke_task_credentials",
"remove_task_identities"
]}
},
"allowed_operations_sha256": {"$ref": "#/$defs/sha256"},
"denied_operations": {"type": "array", "minItems": 12, "uniqueItems": true, "items": {"type": "string"}},
"maximum_operation_count": {"type": "integer", "minimum": 1, "maximum": 10},
"maximum_pr_count": {"const": 1},
"maximum_branch_count": {"const": 1},
"maximum_commit_count": {"const": 1},
"allowed_paths": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}},
"allowed_paths_sha256": {"$ref": "#/$defs/sha256"},
"approved_at": {"type": "string", "format": "date-time", "pattern": "Z$"},
"expires_at": {"type": "string", "format": "date-time", "pattern": "Z$"},
"maximum_lifetime_seconds": {"type": "integer", "minimum": 1, "maximum": 43200},
"auto_revoke": {"const": true},
"required_human_approvals": {"const": 1},
"allowed_human_approvers": {"const": ["owner"]},
"approved_by": {"const": "owner"},
"owner_review_id": {"type": "integer", "minimum": 1},
"owner_review_commit_oid": {"$ref": "#/$defs/oid"},
"approval_plan_id": {"type": "string", "minLength": 3, "maxLength": 192},
"approval_audit_event_id": {"type": "string", "minLength": 3, "maxLength": 192},
"production_runtime_anchor_change": {"const": false},
"production_writes_enabled": {"const": false},
"tag_operations": {"const": false},
"registry_operations": {"const": false},
"baseline_operations": {"const": false},
"deployment_operations": {"const": false},
"force_push_allowed": {"const": false},
"tag_rewrite_allowed": {"const": false},
"direct_main_push_allowed": {"const": false}
},
"$defs": {
"plan": {
"type": "object",
"additionalProperties": false,
"required": [
"document_kind", "schema_id", "schema_version", "payload_sha256",
"payload"
],
"properties": {
"document_kind": {"const": "PLAN"},
"schema_id": {"const": "TASK_SCOPED_GOVERNANCE_BOOTSTRAP_PLAN"},
"schema_version": {"const": 1},
"payload_sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"payload": {"$ref": "#/$defs/planPayload"}
}
},
"planPayload": {
"type": "object",
"additionalProperties": false,
"required": [
"allowed_human_approvers", "allowed_operations", "allowed_operations_sha256",
"allowed_paths", "allowed_paths_sha256", "approval_plan_id", "approval_plan_path",
"approved_by", "auto_revoke", "baseline_operations", "candidate_commit_oid",
"candidate_diff_sha256", "candidate_files_sha256", "candidate_parent_oid",
"candidate_tree_oid", "code_base_oid", "code_base_ref", "credential_scope",
"credential_secret_ref", "denied_operations", "deployment_operations",
"direct_main_push_allowed", "expires_at", "force_push_allowed",
"governance_base_oid", "governance_base_ref", "maximum_branch_count",
"maximum_commit_count", "maximum_lifetime_seconds", "maximum_operation_count",
"maximum_pr_count", "observed_preapproval_operations",
"production_runtime_anchor_change", "production_writes_enabled",
"provision_credential_projection", "provision_publisher", "provision_writer",
"publisher_identity", "publisher_scope", "registry_operations",
"repository_identity", "request_created_at", "request_expires_at",
"request_head_ref", "request_id", "requester_identity",
"required_human_approvals", "required_machine_contexts",
"schema_document_sha256", "schema_id", "schema_version", "tag_operations",
"tag_rewrite_allowed", "target_initial_state", "target_ref",
"validator_policy_sha256", "writer_identity", "writer_scope"
],
"properties": {
"allowed_human_approvers": {"$ref": "#/properties/allowed_human_approvers"},
"allowed_operations": {"$ref": "#/properties/allowed_operations"},
"allowed_operations_sha256": {"$ref": "#/properties/allowed_operations_sha256"},
"allowed_paths": {"$ref": "#/properties/allowed_paths"},
"allowed_paths_sha256": {"$ref": "#/properties/allowed_paths_sha256"},
"approval_plan_id": {"$ref": "#/properties/approval_plan_id"},
"approval_plan_path": {"$ref": "#/properties/approval_plan_path"},
"approved_by": {"$ref": "#/properties/approved_by"},
"auto_revoke": {"$ref": "#/properties/auto_revoke"},
"baseline_operations": {"$ref": "#/properties/baseline_operations"},
"candidate_commit_oid": {"$ref": "#/properties/candidate_commit_oid"},
"candidate_diff_sha256": {"$ref": "#/properties/candidate_diff_sha256"},
"candidate_files_sha256": {"$ref": "#/properties/candidate_files_sha256"},
"candidate_parent_oid": {"$ref": "#/properties/candidate_parent_oid"},
"candidate_tree_oid": {"$ref": "#/properties/candidate_tree_oid"},
"code_base_oid": {"$ref": "#/properties/code_base_oid"},
"code_base_ref": {"$ref": "#/properties/code_base_ref"},
"credential_scope": {"$ref": "#/properties/credential_scope"},
"credential_secret_ref": {"$ref": "#/properties/credential_secret_ref"},
"denied_operations": {"$ref": "#/properties/denied_operations"},
"deployment_operations": {"$ref": "#/properties/deployment_operations"},
"direct_main_push_allowed": {"$ref": "#/properties/direct_main_push_allowed"},
"expires_at": {"$ref": "#/properties/expires_at"},
"force_push_allowed": {"$ref": "#/properties/force_push_allowed"},
"governance_base_oid": {"$ref": "#/properties/governance_base_oid"},
"governance_base_ref": {"$ref": "#/properties/governance_base_ref"},
"maximum_branch_count": {"$ref": "#/properties/maximum_branch_count"},
"maximum_commit_count": {"$ref": "#/properties/maximum_commit_count"},
"maximum_lifetime_seconds": {"$ref": "#/properties/maximum_lifetime_seconds"},
"maximum_operation_count": {"$ref": "#/properties/maximum_operation_count"},
"maximum_pr_count": {"$ref": "#/properties/maximum_pr_count"},
"observed_preapproval_operations": {"$ref": "#/properties/observed_preapproval_operations"},
"production_runtime_anchor_change": {"$ref": "#/properties/production_runtime_anchor_change"},
"production_writes_enabled": {"$ref": "#/properties/production_writes_enabled"},
"provision_credential_projection": {"$ref": "#/properties/provision_credential_projection"},
"provision_publisher": {"$ref": "#/properties/provision_publisher"},
"provision_writer": {"$ref": "#/properties/provision_writer"},
"publisher_identity": {"$ref": "#/properties/publisher_identity"},
"publisher_scope": {"$ref": "#/properties/publisher_scope"},
"registry_operations": {"$ref": "#/properties/registry_operations"},
"repository_identity": {"$ref": "#/properties/repository_identity"},
"request_created_at": {"$ref": "#/properties/request_created_at"},
"request_expires_at": {"$ref": "#/properties/request_expires_at"},
"request_head_ref": {"$ref": "#/properties/request_head_ref"},
"request_id": {"$ref": "#/properties/request_id"},
"requester_identity": {"$ref": "#/properties/requester_identity"},
"required_human_approvals": {"$ref": "#/properties/required_human_approvals"},
"required_machine_contexts": {"$ref": "#/properties/required_machine_contexts"},
"schema_document_sha256": {"$ref": "#/properties/schema_document_sha256"},
"schema_id": {"$ref": "#/properties/schema_id"},
"schema_version": {"$ref": "#/properties/schema_version"},
"tag_operations": {"$ref": "#/properties/tag_operations"},
"tag_rewrite_allowed": {"$ref": "#/properties/tag_rewrite_allowed"},
"target_initial_state": {"$ref": "#/properties/target_initial_state"},
"target_ref": {"$ref": "#/properties/target_ref"},
"validator_policy_sha256": {"$ref": "#/properties/validator_policy_sha256"},
"writer_identity": {"$ref": "#/properties/writer_identity"},
"writer_scope": {"$ref": "#/properties/writer_scope"}
}
},
"oid": {"type": "string", "pattern": "^[0-9a-f]{40}$"},
"sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"identity": {"type": "string", "minLength": 3, "maxLength": 128, "pattern": "^[A-Za-z0-9][A-Za-z0-9_.-]+$"}
}
}
@@ -0,0 +1,64 @@
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"$id": "AIOS_TASK_STATUS_MERGE_GRANT_V1",
"type": "object",
"additionalProperties": false,
"required": [
"schema_id", "schema_version", "repository", "pr_number", "base_oid",
"target_commit", "approved_tree_oid", "manifest_path", "manifest_blob_oid", "manifest_sha256",
"payload_sha256", "status_identity", "merge_identity", "status_contexts",
"status_write_quota", "merge_quota", "merge_method", "branch_push_allowed",
"tag_write_allowed", "main_write_allowed", "registry_write_allowed",
"baseline_write_allowed", "production_write_allowed", "issued_at", "expires_at",
"audit_key_ref", "grant_signer_identity", "grant_signature_namespace",
"status_evidence_sha256", "supersedes_pr_number", "supersedes_head_oid",
"renewal_required"
],
"properties": {
"schema_id": {"const": "AIOS_TASK_STATUS_MERGE_GRANT"},
"schema_version": {"const": 1},
"repository": {"const": "aios/aios"},
"pr_number": {"type": "integer", "minimum": 1},
"base_oid": {"type": "string", "pattern": "^[0-9a-f]{40}$"},
"target_commit": {"type": "string", "pattern": "^[0-9a-f]{40}$"},
"approved_tree_oid": {"type": "string", "pattern": "^[0-9a-f]{40}$"},
"manifest_path": {"type": "string", "pattern": "^approvals/[A-Za-z0-9._/-]+\\.json$"},
"manifest_blob_oid": {"type": "string", "pattern": "^[0-9a-f]{40}$"},
"manifest_sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"payload_sha256": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"status_evidence_sha256": {
"type": "object", "additionalProperties": false,
"required": ["aios/branch-protection", "aios/evidence-closure", "aios/secret-scan", "aios/state-machine", "aios/validator"],
"properties": {
"aios/branch-protection": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"aios/evidence-closure": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"aios/secret-scan": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"aios/state-machine": {"type": "string", "pattern": "^[0-9a-f]{64}$"},
"aios/validator": {"type": "string", "pattern": "^[0-9a-f]{64}$"}
}
},
"supersedes_pr_number": {"const": 36},
"supersedes_head_oid": {"const": "a8644fc172bd8ebbba17a16e6bf586c93fd1e793"},
"renewal_required": {"const": true},
"status_identity": {"enum": ["codex", "gpt"]},
"merge_identity": {"enum": ["codex", "gpt"]},
"status_contexts": {
"type": "array", "minItems": 5, "maxItems": 5, "uniqueItems": true,
"items": {"enum": ["aios/branch-protection", "aios/evidence-closure", "aios/secret-scan", "aios/state-machine", "aios/validator"]}
},
"status_write_quota": {"const": 5},
"merge_quota": {"const": 1},
"merge_method": {"const": "fast-forward-only"},
"branch_push_allowed": {"const": false},
"tag_write_allowed": {"const": false},
"main_write_allowed": {"const": false},
"registry_write_allowed": {"const": false},
"baseline_write_allowed": {"const": false},
"production_write_allowed": {"const": false},
"issued_at": {"type": "string", "format": "date-time"},
"expires_at": {"type": "string", "format": "date-time"},
"audit_key_ref": {"type": "string", "pattern": "^systemd-credential://[A-Za-z0-9_.-]+$"},
"grant_signer_identity": {"const": "aios-task-grant-signer"},
"grant_signature_namespace": {"const": "aios-task-status-merge-grant-v1"}
}
}
@@ -0,0 +1,357 @@
from __future__ import annotations
from datetime import datetime, timedelta, timezone
import json
from pathlib import Path
import sys
import subprocess
import tempfile
import unittest
from unittest import mock
import urllib.error
ROOT = Path(__file__).resolve().parents[2]
sys.path.insert(0, str(ROOT / "services" / "aios-single-owner-governance"))
from aios_single_owner_governance.task_status_merge_broker import ( # noqa: E402
ALLOWED_CONTEXTS,
ContractDenied,
MergeBroker,
QuotaJournal,
StatusBroker,
TaskGrant,
canonical,
load_signed_task_grant,
)
from aios_single_owner_governance.task_credential_broker import TaskCredentialBroker # noqa: E402
from aios_single_owner_governance import task_credential_expiry_sweeper as sweeper # noqa: E402
HEAD = "d" * 40
OLD_HEAD = "a8644fc172bd8ebbba17a16e6bf586c93fd1e793"
BASE = "8814dff20222625b60454c613b61ccf15fa20e51"
def grant() -> dict:
now = datetime.now(timezone.utc).replace(microsecond=0)
value = {
"schema_id": "AIOS_TASK_STATUS_MERGE_GRANT",
"schema_version": 1,
"repository": "aios/aios",
"pr_number": 36,
"base_oid": BASE,
"target_commit": HEAD,
"approved_tree_oid": "3649be2dac8fcea3a79cb1604b2cfb63f6cc0307",
"manifest_path": "approvals/release-campaign/AIOS-V2R1C4-PHASE-B-RENEWAL.json",
"manifest_blob_oid": "d6e4431992e4315799c7f0487f2b12a20d0e2890",
"manifest_sha256": "2555c5e37f77f1d0aac51864733b55ee3e91169ae76bf67e8817de6d1874eea4",
"payload_sha256": "4db7d3fd5aaa00a65eabfce7501f275b5f6c8a2587b6153fa8066ec0dafa5d6d",
"status_evidence_sha256": {context: "1" * 64 for context in ALLOWED_CONTEXTS},
"supersedes_pr_number": 36,
"supersedes_head_oid": OLD_HEAD,
"renewal_required": True,
"status_identity": "codex",
"merge_identity": "codex",
"status_contexts": sorted(ALLOWED_CONTEXTS),
"status_write_quota": 5,
"merge_quota": 1,
"merge_method": "fast-forward-only",
"branch_push_allowed": False,
"tag_write_allowed": False,
"main_write_allowed": False,
"registry_write_allowed": False,
"baseline_write_allowed": False,
"production_write_allowed": False,
"issued_at": now.isoformat().replace("+00:00", "Z"),
"expires_at": (now + timedelta(hours=1)).isoformat().replace("+00:00", "Z"),
"audit_key_ref": "systemd-credential://task-audit-hmac",
"grant_signer_identity": "aios-task-grant-signer",
"grant_signature_namespace": "aios-task-status-merge-grant-v1",
}
value["pr_number"] = 37
return value
class FakeAPI:
def __init__(self, *, with_statuses: bool = False, fail_status_after: int | None = None,
fail_after_merge: bool = False):
self.posts: list[tuple[str, dict]] = []
self.merged = False
self.status_rows = [{"id": index + 1, "context": value, "status": "success", "sha": HEAD,
"description": "task-scoped PASS evidence_sha256=" + "1" * 64,
"creator": {"login": "codex"}} for index, value in enumerate(ALLOWED_CONTEXTS)] if with_statuses else []
self.fail_status_after = fail_status_after
self.fail_after_merge = fail_after_merge
self.base = BASE
def get(self, path: str):
if path.endswith("/reviews"):
return [{
"id": 76,
"state": "APPROVED",
"commit_id": HEAD,
"official": True,
"stale": False,
"dismissed": False,
"submitted_at": datetime.now(timezone.utc).isoformat().replace("+00:00", "Z"),
"user": {"id": 2, "login": "owner"},
}]
if path.endswith("/statuses"):
return list(self.status_rows)
if path.endswith("/branches/governance%2Fapprovals"):
return {"name": "governance/approvals", "commit": {"id": HEAD if self.merged else BASE}}
if path.endswith("/pulls/37"):
return {
"number": 37,
"state": "closed" if self.merged else "open",
"merged": self.merged,
"mergeable": True,
"head": {"sha": HEAD},
"base": {"sha": self.base, "ref": "governance/approvals"},
"merge_commit_sha": HEAD if self.merged else None,
}
raise AssertionError(path)
def post(self, path: str, payload: dict):
self.posts.append((path, payload))
if path.endswith("/merge"):
assert payload == {
"Do": "fast-forward-only",
"head_commit_id": HEAD,
"force_merge": False,
"delete_branch_after_merge": False,
}
self.merged = True
if self.fail_after_merge:
raise ContractDenied("SIMULATED_POST_MERGE_LOSS")
return {"merged": True}
if self.fail_status_after is not None and len(self.status_rows) >= self.fail_status_after:
raise ContractDenied("SIMULATED_STATUS_FAILURE")
row = {"id": len(self.posts), "context": payload["context"], "status": "success", "sha": HEAD,
"description": payload["description"],
"creator": {"login": "codex"}}
self.status_rows.append(row)
return row
def evidence() -> list[dict]:
return [{"context": value, "evidence_sha256": "1" * 64} for value in sorted(ALLOWED_CONTEXTS)]
class TaskStatusMergeBrokerTests(unittest.TestCase):
def setUp(self):
self.temporary = tempfile.TemporaryDirectory()
self.root = Path(self.temporary.name)
self.journals: list[QuotaJournal] = []
def tearDown(self):
for journal in self.journals:
journal.close()
self.temporary.cleanup()
def journal(self, item: TaskGrant) -> QuotaJournal:
value = QuotaJournal(self.root / "journal.sqlite3", item)
self.journals.append(value)
return value
def test_status_broker_publishes_exact_five_and_quota_is_single_use(self):
item = TaskGrant.from_dict(grant())
api = FakeAPI()
journal = self.journal(item)
receipt = StatusBroker(item, journal, api, b"audit-key").publish(evidence())
self.assertEqual(receipt["status"], "PASS")
self.assertEqual(receipt["published_count"], 5)
self.assertEqual({entry[1]["context"] for entry in api.posts}, ALLOWED_CONTEXTS)
with self.assertRaisesRegex(ContractDenied, "STATUS_QUOTA_EXHAUSTED"):
StatusBroker(item, journal, api, b"audit-key").publish(evidence())
def test_merge_broker_uses_fast_forward_only_and_binds_exact_head(self):
item = TaskGrant.from_dict(grant())
api = FakeAPI(with_statuses=True)
journal = self.journal(item)
receipt = MergeBroker(item, journal, api, b"audit-key").merge()
self.assertEqual(receipt["status"], "PASS")
self.assertEqual(receipt["governance_oid"], HEAD)
self.assertTrue(api.merged)
with self.assertRaisesRegex(ContractDenied, "MERGE_QUOTA_EXHAUSTED"):
MergeBroker(item, journal, FakeAPI(with_statuses=True), b"audit-key").merge()
def test_contract_rejects_scope_expansion_secret_and_wrong_identity(self):
value = grant()
value["main_write_allowed"] = True
with self.assertRaisesRegex(ContractDenied, "WRITE_SCOPE_EXPANDED"):
TaskGrant.from_dict(value)
def test_unbound_evidence_fails_closed(self):
item = TaskGrant.from_dict(grant())
changed = evidence()
changed[0]["evidence_sha256"] = "2" * 64
with self.assertRaisesRegex(ContractDenied, "EVIDENCE_SET_INVALID"):
StatusBroker(item, self.journal(item), FakeAPI(), b"audit-key").publish(changed)
def test_grant_requires_detached_asymmetric_signature(self):
grant_path = self.root / "grant.json"
signature_path = self.root / "grant.sig"
allowed_signers = self.root / "allowed_signers"
raw = canonical(grant()) + b"\n"
grant_path.write_bytes(raw)
signature_path.write_text("ssh-signature", encoding="utf-8")
allowed_signers.write_text("aios-task-grant-signer ssh-ed25519 AAAA", encoding="utf-8")
with mock.patch("aios_single_owner_governance.task_status_merge_broker.subprocess.run") as runner:
item = load_signed_task_grant(grant_path, signature_path, allowed_signers)
self.assertEqual(item.raw["pr_number"], 37)
self.assertEqual(runner.call_args.kwargs["input"], raw)
with mock.patch(
"aios_single_owner_governance.task_status_merge_broker.subprocess.run",
side_effect=subprocess.CalledProcessError(255, ["ssh-keygen"]),
):
with self.assertRaisesRegex(ContractDenied, "GRANT_SIGNATURE_INVALID"):
load_signed_task_grant(grant_path, signature_path, allowed_signers)
def test_base_movement_blocks_status_publication_before_side_effect(self):
item = TaskGrant.from_dict(grant())
api = FakeAPI()
api.base = "c" * 40
with self.assertRaisesRegex(ContractDenied, "PR_BINDING_INVALID"):
StatusBroker(item, self.journal(item), api, b"audit-key").publish(evidence())
self.assertEqual(api.posts, [])
def test_credential_provision_rechecks_local_owner_and_refs_before_issuance(self):
item = TaskGrant.from_dict(grant())
broker = TaskCredentialBroker(item, self.root / "audit", b"audit-key")
with mock.patch("aios_single_owner_governance.task_credential_broker.os.geteuid", return_value=0, create=True), \
mock.patch("aios_single_owner_governance.task_credential_broker._safe_absolute"), \
mock.patch("aios_single_owner_governance.task_credential_broker._verify_local_governance_binding", side_effect=ContractDenied("LOCAL_OWNER_APPROVAL_MISSING")), \
mock.patch("aios_single_owner_governance.task_credential_broker.subprocess.run") as runner:
with self.assertRaisesRegex(ContractDenied, "LOCAL_OWNER_APPROVAL_MISSING"):
broker.provision(
identity="codex",
token_name="pr37-dddddddddddd-status",
encrypted_path=Path("/run/aios-task-credential-broker/status.cred"),
)
runner.assert_not_called()
value = grant()
value["status_identity"] = "gitops-bot"
with self.assertRaisesRegex(ContractDenied, "IDENTITY_NOT_ALLOWED"):
TaskGrant.from_dict(value)
def test_expiry_sweeper_revokes_projected_token_after_grant_expiry(self):
item = TaskGrant.from_dict(grant())
runtime_root = self.root / "runtime"
credential_root = self.root / "credentials"
task_dir = runtime_root / "task-37"
audit_dir = task_dir / "audit"
audit_dir.mkdir(parents=True)
credential_root.mkdir()
(task_dir / "grant.json").write_text("{}", encoding="utf-8")
(task_dir / "grant.sig").write_text("signature", encoding="utf-8")
token_name = "pr37-dddddddddddd-status"
encrypted_path = credential_root / "status.cred"
encrypted_path.write_text("encrypted", encoding="utf-8")
(credential_root / "task-37-audit.cred").write_text("encrypted-audit-key", encoding="utf-8")
real_broker = TaskCredentialBroker(item, audit_dir, b"audit-key")
receipt = real_broker._audit({
"status": "PASS", "operation": "credential_provision", "identity": "codex",
"token_name": token_name, "token_id": 101, "token_uid": 7,
"grant_sha256": item.digest,
"credential_ref": "systemd-credential-encrypted://status.cred",
})
real_broker.validate_provision_receipt(receipt, encrypted_path)
tampered = dict(receipt)
tampered["token_id"] = 102
with self.assertRaisesRegex(ContractDenied, "PROVISION_RECEIPT_INVALID"):
real_broker.validate_provision_receipt(tampered, encrypted_path)
fake_broker = mock.Mock()
fake_broker.revoke.return_value = {"status": "PASS", "old_token_http_status": 401}
with mock.patch.object(sweeper, "RUNTIME_ROOT", runtime_root), \
mock.patch.object(sweeper, "CREDENTIAL_ROOT", credential_root), \
mock.patch.object(sweeper.os, "geteuid", return_value=0, create=True), \
mock.patch.object(sweeper, "load_signed_task_grant", return_value=item), \
mock.patch.object(sweeper.subprocess, "run", return_value=mock.Mock(stdout=b"audit-key")), \
mock.patch.object(sweeper, "TaskCredentialBroker", return_value=fake_broker) as broker_type:
results = sweeper.sweep(runtime_root, self.root / "allowed_signers", now=item.expires_at)
self.assertEqual(results, [{"status": "PASS", "old_token_http_status": 401}])
broker_type.assert_called_once_with(item, audit_dir, b"audit-key")
fake_broker.revoke.assert_called_once()
def test_revocation_is_exact_access_token_row_only_and_proves_http_401(self):
item = TaskGrant.from_dict(grant())
broker = TaskCredentialBroker(item, self.root / "revoke-audit", b"audit-key")
token_name = "pr37-dddddddddddd-status"
receipt = broker._audit({
"status": "PASS", "operation": "credential_provision", "identity": "codex",
"token_name": token_name, "token_id": 101, "token_uid": 7,
"grant_sha256": item.digest,
"credential_ref": "systemd-credential-encrypted://status.cred",
})
response = mock.MagicMock()
response.__enter__.return_value.status = 200
unauthorized = urllib.error.HTTPError("http://127.0.0.1:3000/api/v1/repos/aios/aios", 401, "Unauthorized", {}, None)
write_connection = mock.MagicMock()
write_connection.execute.return_value.rowcount = 1
read_connection = mock.MagicMock()
read_connection.execute.return_value.fetchone.return_value = (0,)
with mock.patch("aios_single_owner_governance.task_credential_broker.os.geteuid", return_value=0, create=True), \
mock.patch("aios_single_owner_governance.task_credential_broker._safe_absolute"), \
mock.patch("aios_single_owner_governance.task_credential_broker.subprocess.run", return_value=mock.Mock(stdout=b"x" * 40)), \
mock.patch("aios_single_owner_governance.task_credential_broker.sqlite3.connect", side_effect=[write_connection, read_connection]) as connect, \
mock.patch("aios_single_owner_governance.task_credential_broker.urllib.request.urlopen", side_effect=[response, unauthorized]) as urlopen:
result = broker.revoke(receipt=receipt, encrypted_path=Path("/run/aios-task-credential-broker/status.cred"))
self.assertEqual(result["old_token_http_status"], 401)
self.assertIn("/repos/aios/aios", urlopen.call_args_list[0].args[0].full_url)
delete_sql = write_connection.execute.call_args_list[1].args[0]
self.assertIn("DELETE FROM access_token", delete_sql)
self.assertNotIn("commit_status", delete_sql)
self.assertIn("mode=ro", connect.call_args_list[1].args[0])
value = grant()
value["token"] = "plaintext"
with self.assertRaisesRegex(ContractDenied, "GRANT_FIELDS_INVALID"):
TaskGrant.from_dict(value)
def test_audit_chain_is_content_addressed_and_contains_no_secret(self):
item = TaskGrant.from_dict(grant())
journal = self.journal(item)
receipt = StatusBroker(item, journal, FakeAPI(), b"audit-key").publish(evidence())
serialized = json.dumps(receipt, sort_keys=True)
self.assertNotIn("audit-key", serialized)
self.assertEqual(len(receipt["audit_signature"]), 64)
self.assertTrue(journal.verify_chain())
def test_credential_broker_is_root_only_and_never_returns_a_token(self):
item = TaskGrant.from_dict(grant())
broker = TaskCredentialBroker(item, self.root / "audit", b"audit-key")
with mock.patch("aios_single_owner_governance.task_credential_broker.os.geteuid", return_value=1000, create=True):
with self.assertRaisesRegex(ContractDenied, "ROOT_BROKER_REQUIRED"):
broker.provision(
identity="codex",
token_name="pr36-a8644fc172bd-status",
encrypted_path=Path("/run/aios-task-credential-broker/status.cred"),
)
def test_partial_status_side_effects_are_reconciled_without_duplicate_writes(self):
item = TaskGrant.from_dict(grant())
api = FakeAPI(fail_status_after=2)
journal = self.journal(item)
with self.assertRaisesRegex(ContractDenied, "SIMULATED_STATUS_FAILURE"):
StatusBroker(item, journal, api, b"audit-key").publish(evidence())
self.assertEqual(len(api.status_rows), 2)
api.fail_status_after = None
receipt = StatusBroker(item, journal, api, b"audit-key").publish(evidence())
self.assertEqual(receipt["published_count"], 5)
self.assertEqual(len(api.status_rows), 5)
def test_post_merge_response_loss_is_reconciled_from_exact_remote_ref(self):
item = TaskGrant.from_dict(grant())
api = FakeAPI(with_statuses=True, fail_after_merge=True)
journal = self.journal(item)
with self.assertRaisesRegex(ContractDenied, "SIMULATED_POST_MERGE_LOSS"):
MergeBroker(item, journal, api, b"audit-key").merge()
api.fail_after_merge = False
receipt = MergeBroker(item, journal, api, b"audit-key").merge()
self.assertTrue(receipt["reconciled"])
self.assertEqual(receipt["governance_oid"], HEAD)
if __name__ == "__main__":
unittest.main()
@@ -1,228 +0,0 @@
import json
import tempfile
import threading
import unittest
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
from pathlib import Path
import os
import sys
ROOT = os.getcwd()
sys.path.insert(0, str(Path(ROOT) / "active-runtime"))
from app.task_plane.workers.command_policy import CommandPolicy
from app.task_plane.workers.task_client import (
CredentialSource,
StageAClientConfig,
TaskClientAuthError,
TaskClientProtocolError,
TaskClientResponseTooLargeError,
TaskPlaneClient,
)
def _start_server(responses):
class Handler(BaseHTTPRequestHandler):
request_count = 0
seen = []
def do_POST(self):
index = Handler.request_count
Handler.request_count += 1
payload_length = int(self.headers.get("Content-Length", "0"))
payload = self.rfile.read(payload_length)
try:
payload_obj = json.loads(payload.decode("utf-8") or "{}")
except Exception:
payload_obj = {"raw": payload.decode("utf-8", errors="replace")}
Handler.seen.append((self.path, payload_obj))
status, response_obj = responses[min(index, len(responses) - 1)]
body = json.dumps(response_obj).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 log_message(self, *_args, **_kwargs):
return
server = ThreadingHTTPServer(("127.0.0.1", 0), Handler)
thread = threading.Thread(target=server.serve_forever, daemon=True)
thread.start()
return server, thread, Handler
def _stop_server(server, thread):
server.shutdown()
server.server_close()
thread.join(timeout=2)
class CodexWorkerCommandPolicyTests(unittest.TestCase):
def test_rejects_revision_and_path_injection(self):
with tempfile.TemporaryDirectory() as directory:
root = Path(directory)
policy = CommandPolicy(root, root / "results")
with self.assertRaises(ValueError):
policy.build("git-show", oid="HEAD~1", paths=["active-runtime/app/task_plane/api.py"])
with self.assertRaises(ValueError):
policy.build("pytest", oid="0" * 40, paths=["../outside"])
class CodexWorkerClientStageBTests(unittest.TestCase):
def test_client_retry_on_retryable_status(self):
server, thread, handler = _start_server([(503, {"error": "try again"}), (200, {"ok": True})])
try:
client = TaskPlaneClient(
StageAClientConfig(base_url=f"http://127.0.0.1:{server.server_port}"),
token="stage-b-token-" + "x" * 32,
)
body = client._post("/tests/retry", {"probe": "x"}, idempotency_key="retry")
self.assertEqual(body, {"ok": True})
self.assertEqual(handler.request_count, 2)
self.assertTrue(handler.seen[0][0].startswith("/tests/retry"))
finally:
_stop_server(server, thread)
def test_client_stops_retry_on_auth_error(self):
server, thread, handler = _start_server([(403, {"error": "denied"})])
try:
client = TaskPlaneClient(
StageAClientConfig(base_url=f"http://127.0.0.1:{server.server_port}"),
token="stage-b-token-" + "x" * 32,
)
with self.assertRaises(TaskClientAuthError):
client._post("/tests/auth", {"probe": "x"}, idempotency_key="auth")
self.assertEqual(handler.request_count, 1)
finally:
_stop_server(server, thread)
def test_client_rejects_oversize_request_and_response(self):
server, thread, _ = _start_server([(200, {"ok": True})])
try:
small = TaskPlaneClient(
StageAClientConfig(
base_url=f"http://127.0.0.1:{server.server_port}",
max_request_bytes=8,
),
token="stage-b-token-" + "x" * 32,
)
with self.assertRaises(TaskClientResponseTooLargeError):
small._post("/tests/request", {"probe": "too-large"}, idempotency_key="req")
finally:
_stop_server(server, thread)
oversize = {"blob": "x" * 1_100_000}
server, thread, _ = _start_server([(200, oversize)])
try:
client = TaskPlaneClient(
StageAClientConfig(base_url=f"http://127.0.0.1:{server.server_port}"),
token="stage-b-token-" + "x" * 32,
)
with self.assertRaises(TaskClientResponseTooLargeError):
client._post("/tests/response", {"probe": "ok"}, idempotency_key="resp")
finally:
_stop_server(server, thread)
def test_client_credential_source_symlink_and_mode(self):
with tempfile.TemporaryDirectory() as directory:
directory = Path(directory)
token_file = directory / "token"
token_file.write_text("x" * 32, encoding="utf-8")
token_file.chmod(0o600)
import grp
import pwd
owner = pwd.getpwuid(os.getuid()).pw_name
group = grp.getgrgid(os.getgid()).gr_name
source = CredentialSource(
token_file,
token_owner=owner,
token_group=group,
expected_mode=0o600,
)
self.assertEqual(source.read_token(), "x" * 32)
symlink = directory / "token-link"
symlink.symlink_to(token_file)
with self.assertRaises(TaskClientAuthError):
CredentialSource(
symlink,
token_owner=owner,
token_group=group,
expected_mode=0o600,
).read_token()
bad_mode = directory / "bad-mode"
bad_mode.write_text("value", encoding="utf-8")
bad_mode.chmod(0o644)
with self.assertRaises(TaskClientAuthError):
CredentialSource(
bad_mode,
token_owner=owner,
token_group=group,
expected_mode=0o600,
).read_token()
def test_client_rejects_missing_claim_id_and_reports_heartbeat_defaults(self):
client = TaskPlaneClient(StageAClientConfig(), token="stage-b-token-" + "x" * 32)
with self.assertRaises(TaskClientProtocolError):
client.progress("task-id", claim_id="", progress=10, stage="RUN")
with self.assertRaises(TaskClientProtocolError):
client.result(
"task-id",
claim_id="",
status="COMPLETED",
outputs=[],
evidence=[],
started_at="",
completed_at="",
)
with self.assertRaises(TaskClientProtocolError):
client.fail("task-id", claim_id="")
def test_heartbeat_request_uses_default_lease(self):
captured = {}
def handler_factory(responses):
class Handler(BaseHTTPRequestHandler):
def do_POST(self):
payload_length = int(self.headers.get("Content-Length", "0"))
captured["path"] = self.path
captured["payload"] = json.loads(self.rfile.read(payload_length).decode("utf-8") or "{}")
status, response_obj = responses[min(responses_index[0], len(responses) - 1)]
responses_index[0] += 1
response = json.dumps(response_obj).encode("utf-8")
self.send_response(status)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(response)))
self.end_headers()
self.wfile.write(response)
def log_message(self, *_args, **_kwargs):
return
return Handler
responses_index = [0]
server = ThreadingHTTPServer(("127.0.0.1", 0), handler_factory([(200, {"claim_id": "x"}), (200, {"ok": True})]))
thread = threading.Thread(target=server.serve_forever, daemon=True)
thread.start()
try:
client = TaskPlaneClient(
StageAClientConfig(base_url=f"http://127.0.0.1:{server.server_port}"),
token="stage-b-token-" + "x" * 32,
)
client.claim_heartbeat("task-id", claim_id="claim-id")
self.assertEqual(captured["payload"], {"claim_id": "claim-id", "lease_seconds": 120})
self.assertTrue(captured["path"].endswith("/tasks/task-id/heartbeat"))
captured["payload"] = None
client.worker_heartbeat("worker-1")
self.assertEqual(captured["payload"], {})
finally:
_stop_server(server, thread)
@@ -1,90 +0,0 @@
import os
import stat
import tempfile
import unittest
from pathlib import Path
ROOT = os.getcwd()
import sys
sys.path.insert(0, str(Path(ROOT) / "active-runtime"))
from app.task_plane.workers.codex_review_test import CodexReviewTaskPolicy
from app.task_plane.workers.result_attestation import TaskResultEnvelope, TrustPolicy, task_result_envelope
from app.task_plane.workers.workspace import TaskWorkspace
class CodexWorkerWorkspaceRecoveryTests(unittest.TestCase):
def test_workspace_permissions_and_cleanup(self):
with tempfile.TemporaryDirectory() as directory:
root_path = Path(directory) / "task-root"
with TaskWorkspace.create(root_path, task_id="task-01", claim_id="claim-01") as workspace:
for path in (
workspace.layout.workspace_root,
workspace.layout.repo_root,
workspace.layout.result_root,
workspace.layout.home,
workspace.layout.tmp,
):
self.assertEqual(stat.S_IMODE(path.stat().st_mode), 0o700)
result_path = workspace.write_result(name="result.json", payload="{}")
self.assertTrue(result_path.exists())
self.assertEqual(stat.S_IMODE(result_path.stat().st_mode), 0o600)
self.assertFalse(root_path.exists())
def test_result_envelope_validates_required_contract_fields(self):
envelope = task_result_envelope(
task_id="task-01",
claim_id="claim-01",
worker_identity="spiffe://aios/agent/codex/review-01",
status="COMPLETED",
outputs=[],
evidence=[],
started_at="2026-07-24T00:00:00Z",
completed_at="2026-07-24T00:00:01Z",
)
payload = envelope.to_dict()
self.assertEqual(payload["production_trust"], False)
self.assertEqual(payload["trust_level"], TrustPolicy.SHADOW_ATTESTED.value)
self.assertEqual(payload["task_id"], "task-01")
invalid = TaskResultEnvelope(
task_id="",
claim_id="claim",
worker_identity="worker",
status="FAILED",
outputs=[],
evidence=[],
started_at="",
completed_at="",
production_trust=False,
)
with self.assertRaises(ValueError):
invalid.validate()
def test_shadow_policy_enforces_concurrency_and_timeboxes(self):
policy = CodexReviewTaskPolicy(worker_id="worker-01", identity="identity")
self.assertEqual(policy.max_concurrency, 1)
self.assertEqual(policy.heartbeat_interval_seconds, 15)
self.assertEqual(policy.claim_lease_seconds, 120)
valid_task = {
"risk": "low",
"metadata": {"production_side_effects": False},
}
policy.assert_shadow_only_task(valid_task)
with self.assertRaises(Exception):
policy.assert_shadow_only_task(
{
"risk": "critical",
"metadata": {"production_side_effects": False},
}
)
with self.assertRaises(Exception):
CodexReviewTaskPolicy(
worker_id="worker-01",
identity="identity",
max_concurrency=2,
).assert_shadow_only_task(valid_task)
@@ -1,83 +0,0 @@
import os
import tempfile
import unittest
from pathlib import Path
ROOT = os.getcwd()
import sys
sys.path.insert(0, str(Path(ROOT) / "active-runtime"))
from app.task_plane.workers.command_policy import CommandPolicy
from app.task_plane.workers.runner import CommandDisallowedError, SafeCommandRunner, CommandPolicyError
from app.task_plane.workers.workspace import TaskWorkspace
class CodexWorkerRunnerSecurityTests(unittest.TestCase):
def test_runner_only_allows_fixed_command_set(self):
with tempfile.TemporaryDirectory() as directory:
with TaskWorkspace.create(Path(directory) / "workspace", task_id="task-fixed", claim_id="claim-fixed") as workspace:
runner = SafeCommandRunner(workspace.layout.repo_root, workspace.layout.result_root)
with self.assertRaises(CommandDisallowedError):
runner.run("shell", oid="0" * 40)
with self.assertRaises(CommandDisallowedError):
runner.run("bash", oid="0" * 40, paths=["tests/task_plane/public_interface"])
def test_runner_rejects_shell_like_and_eval_inputs(self):
with tempfile.TemporaryDirectory() as directory:
with TaskWorkspace.create(Path(directory) / "workspace", task_id="task-shell", claim_id="claim-shell") as workspace:
runner = SafeCommandRunner(workspace.layout.repo_root, workspace.layout.result_root)
CommandPolicy(workspace.layout.repo_root, workspace.layout.result_root).build(
"pytest",
oid="0" * 40,
paths=["tests/task_plane/public_interface"],
)
with self.assertRaises(CommandDisallowedError):
runner.run("pytest", oid="0" * 40, paths=["tests/task_plane/public_interface;touch /tmp/x"])
with self.assertRaises(CommandDisallowedError):
runner.run("pytest", oid="0" * 40, paths=["tests/task_plane/public_interface", "eval"])
with self.assertRaises(CommandDisallowedError):
runner.run("pytest", oid="0" * 40, paths=["tests/task_plane/public_interface", "bash"])
def test_runner_rejects_revision_expression_and_symlink_paths(self):
with tempfile.TemporaryDirectory() as directory:
with TaskWorkspace.create(Path(directory) / "workspace", task_id="task-revision", claim_id="claim-revision") as workspace:
runner = SafeCommandRunner(workspace.layout.repo_root, workspace.layout.result_root)
policy_root = workspace.layout.repo_root
(policy_root / "tests" / "task_plane" / "public_interface").mkdir(parents=True, exist_ok=True)
with self.assertRaises(ValueError):
runner.run("git-show", oid="HEAD~1", paths=["active-runtime/app/task_plane/worker.py"])
link_target = policy_root / "tests" / "task_plane" / "public_interface" / "link"
link_target.symlink_to(Path("/etc/passwd"), target_is_directory=False)
with self.assertRaises(CommandPolicyError):
runner.run("git-show", oid="0" * 40, paths=["tests/task_plane/public_interface/link"])
def test_runner_rejects_network_tokens_and_output_escape(self):
with tempfile.TemporaryDirectory() as directory:
with TaskWorkspace.create(Path(directory) / "workspace", task_id="task-net", claim_id="claim-net") as workspace:
runner = SafeCommandRunner(workspace.layout.repo_root, workspace.layout.result_root)
with self.assertRaises(CommandDisallowedError):
runner.run("git-show", oid="0" * 40, paths=["https://bad.example/attack"])
with self.assertRaises(CommandPolicyError):
runner.run(
"acceptance",
oid="0" * 40,
paths=["active-runtime"],
output=workspace.layout.home.parent / "escape.json",
)
def test_runner_accepts_nested_allowlisted_paths_and_rejects_secret_env(self):
with tempfile.TemporaryDirectory() as directory:
with TaskWorkspace.create(Path(directory) / "workspace", task_id="task-safe", claim_id="claim-safe") as workspace:
runner = SafeCommandRunner(workspace.layout.repo_root, workspace.layout.result_root)
command = runner.build(
"pytest",
oid="0" * 40,
paths=["tests/task_plane/public_interface"],
)
self.assertEqual(command[-1], "tests/task_plane/public_interface")
with self.assertRaises(Exception):
runner.run("diff-check", oid="0" * 40, env={"API_TOKEN": "secret"})
@@ -0,0 +1,417 @@
from __future__ import annotations
import json
import os
import tempfile
import unittest
from datetime import datetime, timedelta, timezone
from pathlib import Path
from unittest import mock
import aios_isolated_writer_policy as writer_policy
import isolated_writer_path_policy as path_policy
from isolated_writer_authz import AuthorizationError, _validate_grant
TARGET = "deploy/systemd/aios-codex-review-test-worker.service"
BRANCH = "patch/codex-review-test-worker-20260724"
AUDIENCE = "aios-codex-review-worker-writer.service"
VALID_UNIT = """\
[Unit]
Description=AIOS Codex Review/Test Worker
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=aiman
Group=gitops
WorkingDirectory=/usr/libexec/aios-codex-review-test-worker/current
Environment=AIOS_CODEX_WORKER_MODE=shadow
Environment=AIOS_TASK_PLANE_EXECUTION_ENABLED=false
Environment=PYTHONDONTWRITEBYTECODE=1
ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test
Restart=on-failure
RestartSec=2
NoNewPrivileges=true
PrivateTmp=true
PrivateDevices=true
ProtectSystem=strict
ProtectHome=true
ProtectKernelTunables=true
ProtectKernelModules=true
ProtectControlGroups=true
LockPersonality=true
RestrictSUIDSGID=true
RestrictRealtime=true
MemoryDenyWriteExecute=true
RuntimeDirectory=aios-codex-review-test-worker
StateDirectory=aios-codex-review-test-worker
CacheDirectory=aios-codex-review-test-worker
ReadOnlyPaths=/data/aios-gitops/repo.git
ReadOnlyPaths=/usr/libexec/aios-codex-review-test-worker
ReadWritePaths=/run/aios-codex-review-test-worker
ReadWritePaths=/var/lib/aios-codex-review-test-worker
ReadWritePaths=/var/cache/aios-codex-review-test-worker
UMask=0077
[Install]
WantedBy=multi-user.target
"""
def document(*, paths=None, **updates):
value = {
"schema_version": 1,
"policy_id": "codex-review-worker-path-policy-v1",
"audience": AUDIENCE,
"repository_identity": "aios/aios",
"allowed_branch": BRANCH,
"allowed_operations": {
"commit_file.atomic": {
"exact_paths": paths or [TARGET],
"max_content_bytes": 32768,
"content_profile": "systemd-codex-review-worker-v1",
}
},
}
value.update(updates)
return value
class ExactPathPolicyTests(unittest.TestCase):
def setUp(self):
self.saved = dict(os.environ)
self.temp = tempfile.TemporaryDirectory()
self.root = Path(self.temp.name)
self.policy_dir = self.root / "policies"
self.policy_dir.mkdir(mode=0o750)
self.policy_file = self.policy_dir / "writer.json"
self.workspace = self.root / "workspace"
self.workspace.mkdir(mode=0o700)
os.environ.update(
{
"AIOS_GITOPS_ISOLATED_WRITER_ENFORCEMENT": "required",
"AIOS_GITOPS_SERVICE_AUDIENCE": AUDIENCE,
"AIOS_GITOPS_REPOSITORY_IDENTITY": "aios/aios",
"AIOS_GITOPS_ALLOWED_BRANCH": BRANCH,
}
)
def tearDown(self):
path_policy.clear_path_policy_cache()
os.environ.clear()
os.environ.update(self.saved)
self.temp.cleanup()
def write_policy(self, value=None):
payload = document() if value is None else value
raw = (
json.dumps(payload, ensure_ascii=False, sort_keys=True, separators=(",", ":"))
+ "\n"
)
self.policy_file.write_text(raw, encoding="utf-8")
self.policy_file.chmod(0o640)
return path_policy.load_path_policy(
self.policy_file,
expected_owner_uid=os.getuid(),
expected_group_gid=os.getgid(),
)
def configured(self, loaded):
return mock.patch.object(
path_policy,
"configured_path_policy",
return_value=loaded,
)
def test_exact_systemd_path_and_exact_token_path_are_allowed(self):
loaded = self.write_policy()
with self.configured(loaded):
self.assertEqual(TARGET, writer_policy.validate_path(TARGET, self.workspace))
writer_policy.validate_content_for_path(TARGET, VALID_UNIT)
def test_token_path_cannot_expand_service_policy(self):
loaded = self.write_policy(document(paths=["deploy/systemd/other.service"]))
with self.configured(loaded), self.assertRaisesRegex(
PermissionError, "isolated_writer_service_path_rejected"
):
writer_policy.validate_path(TARGET, self.workspace)
def test_service_policy_cannot_expand_token_path(self):
now = datetime.now(timezone.utc)
grant = {
"schema_version": 2,
"audience": AUDIENCE,
"source_cidrs": ["127.0.0.1/32"],
"created_at": (now - timedelta(seconds=5)).isoformat(),
"not_before": (now - timedelta(seconds=2)).isoformat(),
"expires_at": (now + timedelta(minutes=5)).isoformat(),
"revoked": False,
"allowed_operations": ["commit_file.atomic"],
"allowed_branch": BRANCH,
"allowed_paths": ["deploy/systemd/other.service"],
"approved_base_oid": "a" * 40,
}
with mock.patch(
"isolated_writer_authz._git_is_ancestor", return_value=True
), self.assertRaisesRegex(AuthorizationError, "writer_token_path_rejected"):
_validate_grant(
grant,
audience=AUDIENCE,
source_ip="127.0.0.1",
operation="commit_file.atomic",
branch=BRANCH,
path=TARGET,
workspace=self.workspace,
current_time=now,
)
def test_other_service_file_is_rejected(self):
loaded = self.write_policy()
with self.configured(loaded), self.assertRaisesRegex(
PermissionError, "isolated_writer_service_path_rejected"
):
writer_policy.validate_path(
"deploy/systemd/other.service", self.workspace
)
def test_path_traversal_is_rejected(self):
for value in ("deploy/systemd/../x", "../deploy/systemd/x"):
with self.subTest(value=value), self.assertRaises(PermissionError):
writer_policy.validate_path(value, self.workspace)
def test_url_encoded_traversal_is_rejected(self):
with self.assertRaises(PermissionError):
writer_policy.validate_path(
"deploy/systemd/%2e%2e/x", self.workspace
)
def test_symlink_policy_file_is_rejected(self):
self.write_policy()
link = self.policy_dir / "link.json"
link.symlink_to(self.policy_file)
with self.assertRaisesRegex(
path_policy.PathPolicyError, "isolated_writer_path_policy_symlink_rejected"
):
path_policy.load_path_policy(
link,
expected_owner_uid=os.getuid(),
expected_group_gid=os.getgid(),
)
def test_world_writable_policy_file_is_rejected(self):
self.write_policy()
self.policy_file.chmod(0o646)
with self.assertRaisesRegex(
path_policy.PathPolicyError,
"isolated_writer_path_policy_permissions_rejected",
):
path_policy.load_path_policy(
self.policy_file,
expected_owner_uid=os.getuid(),
expected_group_gid=os.getgid(),
)
def test_unknown_policy_field_is_rejected(self):
value = document()
value["unexpected"] = True
with self.assertRaisesRegex(
path_policy.PathPolicyError,
"isolated_writer_path_policy_fields_rejected",
):
self.write_policy(value)
def test_audience_mismatch_is_rejected(self):
loaded = self.write_policy()
os.environ["AIOS_GITOPS_PATH_POLICY_FILE"] = str(self.policy_file)
os.environ["AIOS_GITOPS_SERVICE_AUDIENCE"] = "other.service"
path_policy.clear_path_policy_cache()
with mock.patch.object(
path_policy, "load_path_policy", return_value=loaded
), self.assertRaisesRegex(
path_policy.PathPolicyError,
"isolated_writer_path_policy_audience_rejected",
):
path_policy.configured_path_policy()
def test_branch_mismatch_is_rejected(self):
loaded = self.write_policy()
os.environ["AIOS_GITOPS_PATH_POLICY_FILE"] = str(self.policy_file)
os.environ["AIOS_GITOPS_ALLOWED_BRANCH"] = "patch/other"
path_policy.clear_path_policy_cache()
with mock.patch.object(
path_policy, "load_path_policy", return_value=loaded
), self.assertRaisesRegex(
path_policy.PathPolicyError,
"isolated_writer_path_policy_branch_rejected",
):
path_policy.configured_path_policy()
def assert_profile_rejected(self, content):
loaded = self.write_policy()
with self.configured(loaded), self.assertRaisesRegex(
PermissionError, "isolated_writer_systemd_profile_rejected"
):
writer_policy.validate_content_for_path(TARGET, content)
def test_disallowed_execution_and_credential_directives_are_rejected(self):
directives = (
"ExecStartPre=/usr/bin/id",
"ExecStartPost=/usr/bin/id",
"ExecReload=/usr/bin/id",
"ExecStop=/usr/bin/id",
"ExecStopPost=/usr/bin/id",
"ExecCondition=/usr/bin/true",
"EnvironmentFile=/run/worker.env",
"PassEnvironment=PATH",
"LoadCredential=worker:/run/worker",
"SetCredential=worker:value",
"ImportCredential=worker",
"StandardInput=socket",
"StandardOutput=socket",
)
for directive in directives:
with self.subTest(directive=directive):
self.assert_profile_rejected(
VALID_UNIT.replace(
"Restart=on-failure",
f"Restart=on-failure\n{directive}",
)
)
def test_disallowed_namespace_and_capability_directives_are_rejected(self):
directives = (
"RootDirectory=/srv/worker",
"RootImage=/srv/worker.raw",
"ReadWritePaths=/",
"BindPaths=/etc:/etc",
"BindReadOnlyPaths=/etc:/etc",
"TemporaryFileSystem=/etc",
"CapabilityBoundingSet=CAP_SYS_ADMIN",
"AmbientCapabilities=CAP_SYS_ADMIN",
"DeviceAllow=/dev/sda rw",
"SupplementaryGroups=docker",
"Sockets=unsafe.socket",
)
for directive in directives:
with self.subTest(directive=directive):
self.assert_profile_rejected(
VALID_UNIT.replace(
"Restart=on-failure",
f"Restart=on-failure\n{directive}",
)
)
def test_duplicate_single_directives_and_sections_are_rejected(self):
bad_values = (
VALID_UNIT.replace("User=aiman", "User=aiman\nUser=aiman"),
VALID_UNIT.replace(
"ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test",
"ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test\n"
"ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test",
),
VALID_UNIT + "\n[Service]\nType=simple\n",
)
for value in bad_values:
with self.subTest(value=value):
self.assert_profile_rejected(value)
def test_empty_reset_continuation_crlf_nul_and_long_lines_are_rejected(self):
bad_values = (
VALID_UNIT.replace(
"ExecStart=/usr/bin/python3 -m task_plane.workers.codex_review_test",
"ExecStart=",
),
VALID_UNIT.replace(
"Restart=on-failure",
"Restart=on-failure\n continuation-injection",
),
VALID_UNIT.replace("\n", "\r\n"),
VALID_UNIT.replace("Restart=on-failure", "Restart=on-failure\x00"),
VALID_UNIT.replace(
"Description=AIOS Codex Review/Test Worker",
"Description=" + ("A" * 4097),
),
)
for value in bad_values:
with self.subTest(kind=repr(value[:80])):
self.assert_profile_rejected(value)
def test_unknown_environment_and_production_execution_are_rejected(self):
bad_values = (
VALID_UNIT.replace(
"Environment=PYTHONDONTWRITEBYTECODE=1",
"Environment=UNKNOWN_KEY=value",
),
VALID_UNIT.replace(
"AIOS_TASK_PLANE_EXECUTION_ENABLED=false",
"AIOS_TASK_PLANE_EXECUTION_ENABLED=true",
),
VALID_UNIT.replace(
"Environment=PYTHONDONTWRITEBYTECODE=1",
"Environment=Authorization: Bearer placeholder",
),
)
for value in bad_values:
with self.subTest(value=value):
self.assert_profile_rejected(value)
def test_identity_working_directory_and_path_prefix_bypasses_are_rejected(self):
bad_values = (
VALID_UNIT.replace("User=aiman", "User=root"),
VALID_UNIT.replace(
"/usr/libexec/aios-codex-review-test-worker/current",
"/data/aios-gitops/worktrees/worker",
),
VALID_UNIT.replace(
"ReadWritePaths=/run/aios-codex-review-test-worker",
"ReadWritePaths=/etc",
),
VALID_UNIT.replace(
"ReadOnlyPaths=/data/aios-gitops/repo.git",
"ReadOnlyPaths=/data",
),
)
for value in bad_values:
with self.subTest(value=value):
self.assert_profile_rejected(value)
def test_unknown_section_directive_and_unicode_lookalike_are_rejected(self):
bad_values = (
VALID_UNIT.replace("[Install]", "[Socket]"),
VALID_UNIT.replace(
"Restart=on-failure",
"Restart=on-failure\nProtectClock=true",
),
VALID_UNIT.replace("ExecStart=", "\u0415xecStart="),
)
for value in bad_values:
with self.subTest(value=value):
self.assert_profile_rejected(value)
def test_invalid_unicode_surrogate_and_missing_final_newline_are_rejected(self):
for value in (VALID_UNIT + "\ud800", VALID_UNIT.rstrip("\n")):
with self.subTest(value=repr(value[-30:])):
self.assert_profile_rejected(value)
def test_writer_request_cannot_modify_policy_file(self):
with self.assertRaises(PermissionError):
writer_policy.validate_path(
"etc/aios-gitops/writer-path-policies/codex-review-worker.json",
self.workspace,
)
def test_coarse_file_and_commit_endpoints_remain_forbidden(self):
for endpoint in ("/api/file", "/api/commit"):
with self.subTest(endpoint=endpoint), self.assertRaisesRegex(
PermissionError, "isolated_writer_operation_forbidden"
):
writer_policy.validate_endpoint(
"POST", endpoint, self.workspace, self.root
)
if __name__ == "__main__":
unittest.main()
+4
View File
@@ -15,6 +15,10 @@ class IsolatedWriterPolicyTests(unittest.TestCase):
os.environ["AIOS_GITOPS_ISOLATED_WRITER_ENFORCEMENT"] = "required"
os.environ["AIOS_GITOPS_ALLOWED_BRANCH"] = "patch/aios-agent-task-control-plane-20260724"
os.environ["AIOS_GITOPS_ALLOWED_BASE_OID"] = "a8e97868976b0dce17b7cb8487eadc1d9c687622"
os.environ["AIOS_GITOPS_TOKEN_POLICY_VERSION_REQUIRED"] = "2"
os.environ["AIOS_GITOPS_SERVICE_AUDIENCE"] = "test-isolated-writer.service"
os.environ["AIOS_GITOPS_TOKEN_REGISTRY_V2"] = "/tmp/test-writer-token-registry.sqlite3"
os.environ["AIOS_GITOPS_WRITER_OPERATION_LEDGER"] = "/tmp/test-writer-operations.sqlite3"
def tearDown(self):
os.environ.clear()
@@ -0,0 +1,471 @@
import hashlib
import json
import os
import sqlite3
import subprocess
import sys
import tempfile
import threading
import time
import unittest
from dataclasses import dataclass
from datetime import datetime, timedelta, timezone
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parents[1] / "active-runtime" / "app"))
import aios_isolated_writer_policy as policy
from isolated_writer_authz import AuthorizationError, authorize, operation_for
from isolated_writer_commit_file import (
AtomicCommitFile,
CommitFileError,
OperationLedger,
SimulatedCrash,
)
from isolated_writer_token_registry import TokenRegistry, token_digest
BRANCH = "patch/codex-review-test-worker-20260724"
AUDIENCE = "aios-codex-review-worker-writer.service"
TASK_ID = "AIOS-CODEX-WRITER-SMOKE-20260724"
TARGET_PATH = "docs/reliability/codex-review-worker-writer-smoke.json"
def run(cwd, *args):
return subprocess.check_output(args, cwd=cwd, text=True).strip()
@dataclass
class DummyGrant:
token_id: str = "test-token-id"
task_id: str = TASK_ID
operation: str = "commit_file.atomic"
record: dict = None
def __post_init__(self):
if self.record is None:
self.record = {"audience": AUDIENCE, "_source_ip": "127.0.0.1"}
class RepositoryCase(unittest.TestCase):
def setUp(self):
self.saved = dict(os.environ)
self.temp = tempfile.TemporaryDirectory()
self.root = Path(self.temp.name)
self.authoritative = self.root / "authoritative.git"
self.gitea = self.root / "gitea.git"
self.seed = self.root / "seed"
self.workspace = self.root / "writer"
subprocess.run(["git", "init", "--bare", str(self.authoritative)], check=True, capture_output=True)
subprocess.run(["git", "init", str(self.seed)], check=True, capture_output=True)
subprocess.run(["git", "config", "user.email", "writer@example.invalid"], cwd=self.seed, check=True)
subprocess.run(["git", "config", "user.name", "Writer Test"], cwd=self.seed, check=True)
(self.seed / "README.md").write_text("base\n", encoding="utf-8")
subprocess.run(["git", "add", "README.md"], cwd=self.seed, check=True)
subprocess.run(["git", "commit", "-m", "base"], cwd=self.seed, check=True, capture_output=True)
subprocess.run(["git", "branch", "-M", "main"], cwd=self.seed, check=True)
subprocess.run(["git", "remote", "add", "origin", str(self.authoritative)], cwd=self.seed, check=True)
subprocess.run(["git", "push", "origin", "main"], cwd=self.seed, check=True, capture_output=True)
self.base = run(self.seed, "git", "rev-parse", "HEAD")
subprocess.run(["git", "checkout", "-b", BRANCH], cwd=self.seed, check=True, capture_output=True)
subprocess.run(["git", "push", "origin", BRANCH], cwd=self.seed, check=True, capture_output=True)
subprocess.run(
["git", "--git-dir", str(self.authoritative), "worktree", "add", str(self.workspace), BRANCH],
check=True,
capture_output=True,
)
subprocess.run(["git", "config", "user.email", "writer@example.invalid"], cwd=self.workspace, check=True)
subprocess.run(["git", "config", "user.name", "Writer Test"], cwd=self.workspace, check=True)
subprocess.run(["git", "clone", "--bare", str(self.authoritative), str(self.gitea)], check=True, capture_output=True)
subprocess.run(["git", "remote", "add", "gitea-http", str(self.gitea)], cwd=self.workspace, check=True)
self.registry = TokenRegistry(self.root / "registry.sqlite3")
os.environ.update({
"AIOS_GITOPS_ALLOWED_BRANCH": BRANCH,
"AIOS_GITOPS_TOKEN_POLICY_VERSION_REQUIRED": "2",
"AIOS_GITOPS_SERVICE_AUDIENCE": AUDIENCE,
"AIOS_GITOPS_ISOLATED_WRITER_ENFORCEMENT": "required",
})
def tearDown(self):
os.environ.clear()
os.environ.update(self.saved)
self.temp.cleanup()
def grant(self, **updates):
now = datetime.now(timezone.utc)
grant = {
"token_id": "smoke-" + hashlib.sha256(os.urandom(16)).hexdigest()[:12],
"audience": AUDIENCE,
"task_id": TASK_ID,
"source_cidrs": ["127.0.0.1/32", "::1/128"],
"allowed_branch": BRANCH,
"approved_base_oid": self.base,
"allowed_operations": [
"runtime.status.read",
"baseline.read",
"patches.read",
"commit_file.atomic",
],
"allowed_paths": [TARGET_PATH],
"not_before": (now - timedelta(seconds=2)).isoformat(),
"expires_at": (now + timedelta(minutes=20)).isoformat(),
"max_uses": {
"runtime.status.read": 2,
"baseline.read": 2,
"patches.read": 2,
"commit_file.atomic": 4,
},
"issued_by": "owner-authorized-local-maintenance-executor",
"created_at": (now - timedelta(seconds=3)).isoformat(),
}
grant.update(updates)
return grant
def issue(self, **updates):
return self.registry.issue(self.grant(**updates))
def auth(self, token, **updates):
args = {
"method": "GET",
"path": "/api/runtime-status",
"source_ip": "127.0.0.1",
"workspace": self.workspace,
}
args.update(updates)
return authorize(self.registry, token, **args)
def request(self, key="writer-smoke-0001", content='{"status":"READY"}\n'):
return {
"branch": BRANCH,
"path": TARGET_PATH,
"content": content,
"message": "chore(task-plane): verify Codex writer endpoint",
"expected_head_oid": run(self.workspace, "git", "rev-parse", "HEAD"),
"idempotency_key": key,
}
def writer(self, crash=None, remote="gitea-http", audit=None):
return AtomicCommitFile(
workspace=self.workspace,
bare_repo=self.authoritative,
ledger=OperationLedger(self.root / "operations.sqlite3"),
remote=remote,
audit=audit or (lambda record: None),
crash_after_state=crash,
)
class TokenPolicyV2Tests(RepositoryCase):
def test_v1_coarse_scope_token_is_rejected(self):
token, record = self.issue()
record["schema_version"] = 1
with self.registry._connect() as db:
db.execute(
"UPDATE token_grants SET grant_json=? WHERE token_id=?",
(json.dumps(record), record["token_id"]),
)
with self.assertRaisesRegex(AuthorizationError, "writer_token_policy_v2_required"):
self.auth(token)
def test_audience_mismatch_is_rejected(self):
token, _ = self.issue(audience="other.service")
with self.assertRaisesRegex(AuthorizationError, "writer_token_audience_rejected"):
self.auth(token)
def test_source_ip_mismatch_is_rejected(self):
token, _ = self.issue(source_cidrs=["192.0.2.0/24"])
with self.assertRaisesRegex(AuthorizationError, "writer_token_source_rejected"):
self.auth(token)
def test_branch_mismatch_is_rejected(self):
token, _ = self.issue(allowed_branch="patch/other")
with self.assertRaisesRegex(AuthorizationError, "writer_token_branch_rejected"):
self.auth(token)
def test_operation_mismatch_is_rejected(self):
token, _ = self.issue(allowed_operations=["baseline.read"])
with self.assertRaisesRegex(AuthorizationError, "writer_token_operation_rejected"):
self.auth(token)
def test_path_mismatch_is_rejected(self):
token, _ = self.issue()
with self.assertRaisesRegex(AuthorizationError, "writer_token_path_rejected"):
self.auth(
token,
method="POST",
path="/api/commit-file",
branch=BRANCH,
target_path="docs/other.json",
)
def test_expired_token_is_rejected(self):
now = datetime.now(timezone.utc)
token, _ = self.issue(
created_at=(now - timedelta(minutes=10)).isoformat(),
not_before=(now - timedelta(minutes=9)).isoformat(),
expires_at=(now - timedelta(seconds=1)).isoformat(),
)
with self.assertRaisesRegex(AuthorizationError, "writer_token_expired"):
self.auth(token)
def test_not_before_token_is_rejected(self):
now = datetime.now(timezone.utc)
token, _ = self.issue(
created_at=now.isoformat(),
not_before=(now + timedelta(minutes=1)).isoformat(),
expires_at=(now + timedelta(minutes=5)).isoformat(),
)
with self.assertRaisesRegex(AuthorizationError, "writer_token_not_yet_valid"):
self.auth(token)
def test_revoked_token_is_rejected(self):
token, grant = self.issue()
self.assertTrue(self.registry.revoke(grant["token_id"]))
with self.assertRaisesRegex(AuthorizationError, "writer_token_revoked"):
self.auth(token)
def test_operation_use_count_is_atomic_and_exhausted(self):
token, _ = self.issue(max_uses={
"runtime.status.read": 1,
"baseline.read": 1,
"patches.read": 1,
"commit_file.atomic": 1,
})
self.auth(token)
with self.assertRaisesRegex(AuthorizationError, "writer_token_operation_exhausted"):
self.auth(token)
def test_concurrent_use_count_never_exceeds_limit(self):
token, _ = self.issue(max_uses={
"runtime.status.read": 2,
"baseline.read": 1,
"patches.read": 1,
"commit_file.atomic": 1,
})
successes, failures = [], []
def invoke():
try:
successes.append(self.auth(token))
except AuthorizationError as exc:
failures.append(exc.code)
threads = [threading.Thread(target=invoke) for _ in range(6)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
self.assertEqual(2, len(successes))
self.assertEqual(4, failures.count("writer_token_operation_exhausted"))
def test_registry_does_not_store_plaintext_token(self):
token, _ = self.issue()
registry_bytes = b"".join(
item.read_bytes()
for item in self.registry.path.parent.glob(self.registry.path.name + "*")
if item.is_file()
)
self.assertNotIn(token.encode(), registry_bytes)
with self.registry._connect() as db:
stored = db.execute("SELECT token_digest FROM token_grants").fetchone()[0]
self.assertEqual(token_digest(token), stored)
def test_coarse_routes_have_no_operation_mapping(self):
for path in ("/api/file", "/api/commit", "/api/tag", "/api/rollback", "/api/model"):
with self.subTest(path=path), self.assertRaises(AuthorizationError) as captured:
operation_for("POST", path)
self.assertEqual(403, captured.exception.status)
def test_route_mapping_is_fixed_not_request_controlled(self):
self.assertEqual("runtime.status.read", operation_for("GET", "/api/runtime-status"))
self.assertEqual("baseline.read", operation_for("GET", "/api/baseline"))
self.assertEqual("patches.read", operation_for("GET", "/api/patches"))
self.assertEqual("commit_file.atomic", operation_for("POST", "/api/commit-file"))
def test_x_forwarded_for_cannot_replace_socket_peer(self):
token, _ = self.issue(source_cidrs=["203.0.113.9/32"])
with self.assertRaisesRegex(AuthorizationError, "writer_token_source_rejected"):
self.auth(token, source_ip="127.0.0.1")
class AtomicCommitFileTests(RepositoryCase):
def test_commit_file_succeeds_and_verifies_bare_and_gitea(self):
result = self.writer().execute(DummyGrant(), self.request())
self.assertEqual("COMPLETED", result["state"])
self.assertEqual(
result["commit_oid"],
run(self.root, "git", "--git-dir", str(self.gitea), "rev-parse", f"refs/heads/{BRANCH}"),
)
def test_same_idempotency_key_returns_same_commit(self):
request = self.request()
first = self.writer().execute(DummyGrant(), request)
count = run(self.workspace, "git", "rev-list", "--count", "HEAD")
second = self.writer().execute(DummyGrant(), request)
self.assertEqual(first["commit_oid"], second["commit_oid"])
self.assertEqual(count, run(self.workspace, "git", "rev-list", "--count", "HEAD"))
self.assertTrue(second["idempotent"])
def test_same_key_with_different_payload_returns_409(self):
request = self.request()
self.writer().execute(DummyGrant(), request)
request["content"] = '{"status":"DIFFERENT"}\n'
with self.assertRaises(CommitFileError) as captured:
self.writer().execute(DummyGrant(), request)
self.assertEqual(409, captured.exception.status)
def test_same_key_from_different_task_returns_409(self):
request = self.request()
self.writer().execute(DummyGrant(), request)
other = DummyGrant(token_id="other-token", task_id="OTHER-TASK")
with self.assertRaisesRegex(CommitFileError, "writer_idempotency_owner_conflict"):
self.writer().execute(other, request)
def test_file_written_crash_is_recoverable(self):
request = self.request()
with self.assertRaises(SimulatedCrash):
self.writer(crash="FILE_WRITTEN").execute(DummyGrant(), request)
result = self.writer().execute(DummyGrant(), request)
self.assertEqual("COMPLETED", result["state"])
def test_committed_crash_is_recoverable_without_second_commit(self):
request = self.request()
with self.assertRaises(SimulatedCrash):
self.writer(crash="COMMITTED").execute(DummyGrant(), request)
committed = run(self.workspace, "git", "rev-parse", "HEAD")
result = self.writer().execute(DummyGrant(), request)
self.assertEqual(committed, result["commit_oid"])
def test_pushed_crash_only_reverifies(self):
request = self.request()
with self.assertRaises(SimulatedCrash):
self.writer(crash="PUSHED").execute(DummyGrant(), request)
result = self.writer().execute(DummyGrant(), request)
self.assertEqual("COMPLETED", result["state"])
def test_push_failure_is_failed_recoverable(self):
request = self.request()
with self.assertRaisesRegex(CommitFileError, "writer_gitea_push_failed"):
self.writer(remote="missing-remote").execute(DummyGrant(), request)
row = OperationLedger(self.root / "operations.sqlite3").get(request["idempotency_key"])
self.assertEqual("FAILED_RECOVERABLE", row["state"])
def test_branch_head_conflict_requires_manual_review(self):
request = self.request()
ledger = OperationLedger(self.root / "operations.sqlite3")
ledger.get_or_create(DummyGrant(), request, __import__("isolated_writer_commit_file").canonical_digest(request))
(self.workspace / "README.md").write_text("drift\n", encoding="utf-8")
subprocess.run(["git", "commit", "-am", "drift"], cwd=self.workspace, check=True, capture_output=True)
with self.assertRaisesRegex(CommitFileError, "writer_branch_head_conflict"):
self.writer().execute(DummyGrant(), request)
self.assertEqual("MANUAL_REVIEW_REQUIRED", ledger.get(request["idempotency_key"])["state"])
def test_extra_staged_file_is_rejected(self):
(self.workspace / "README.md").write_text("staged\n", encoding="utf-8")
subprocess.run(["git", "add", "README.md"], cwd=self.workspace, check=True)
with self.assertRaisesRegex(CommitFileError, "writer_extra_staged_files_rejected"):
self.writer().execute(DummyGrant(), self.request())
def test_path_traversal_and_protected_roots_are_rejected(self):
for path in (
"../docs/x", "%2e%2e/docs/x", "/etc/x", r"C:\temp\x",
r"\\server\share\x", "baseline/current.json", "runtime/x",
):
request = self.request(key="writer-path-" + hashlib.sha256(path.encode()).hexdigest()[:12])
request["path"] = path
with self.subTest(path=path), self.assertRaises((PermissionError, CommitFileError)):
self.writer().execute(DummyGrant(), request)
def test_audit_contains_ids_but_not_content_or_authorization(self):
records = []
request = self.request(content='{"value":"non-secret-body-marker"}\n')
self.writer(audit=records.append).execute(DummyGrant(), request)
encoded = json.dumps(records)
self.assertIn("test-token-id", encoded)
self.assertNotIn("non-secret-body-marker", encoded)
self.assertNotIn("Authorization", encoded)
def test_concurrent_same_idempotency_creates_one_commit(self):
request = self.request()
results, errors = [], []
def invoke():
try:
results.append(self.writer().execute(DummyGrant(), request))
except Exception as exc:
errors.append(exc)
threads = [threading.Thread(target=invoke) for _ in range(4)]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
self.assertFalse(errors)
self.assertEqual(1, len({item["commit_oid"] for item in results}))
def test_different_operations_are_serialized_by_branch_lock(self):
active = 0
maximum = 0
guard = threading.Lock()
class Probe(AtomicCommitFile):
def _execute_locked(inner, grant, data, digest):
nonlocal active, maximum
with guard:
active += 1
maximum = max(maximum, active)
time.sleep(0.05)
with guard:
active -= 1
return {"state": "PROBED"}
probe = Probe(
workspace=self.workspace,
bare_repo=self.authoritative,
ledger=OperationLedger(self.root / "probe.sqlite3"),
remote="gitea-http",
audit=lambda record: None,
)
requests = [self.request(key=f"writer-lock-{index:04d}") for index in range(3)]
threads = [threading.Thread(target=probe.execute, args=(DummyGrant(), item)) for item in requests]
for thread in threads:
thread.start()
for thread in threads:
thread.join()
self.assertEqual(1, maximum)
def test_invalid_expected_head_and_idempotency_are_rejected(self):
request = self.request()
request["expected_head_oid"] = "short"
with self.assertRaisesRegex(CommitFileError, "writer_expected_head_rejected"):
self.writer().execute(DummyGrant(), request)
request = self.request()
request["idempotency_key"] = "../bad"
with self.assertRaisesRegex(CommitFileError, "writer_idempotency_key_rejected"):
self.writer().execute(DummyGrant(), request)
def test_invalid_message_and_nul_content_are_rejected(self):
request = self.request()
request["message"] = "bad\nmessage"
with self.assertRaisesRegex(CommitFileError, "writer_message_rejected"):
self.writer().execute(DummyGrant(), request)
request = self.request()
request["content"] = "bad\x00content"
with self.assertRaisesRegex(CommitFileError, "writer_content_rejected"):
self.writer().execute(DummyGrant(), request)
def test_force_flags_are_403_and_unknown_fields_are_rejected(self):
for field in ("force", "force_push"):
request = self.request(key=f"writer-force-{field}")
request[field] = True
with self.subTest(field=field), self.assertRaises(CommitFileError) as captured:
self.writer().execute(DummyGrant(), request)
self.assertEqual(403, captured.exception.status)
request = self.request(key="writer-extra-field")
request["operation"] = "commit_file.atomic"
with self.assertRaisesRegex(CommitFileError, "writer_request_fields_rejected"):
self.writer().execute(DummyGrant(), request)
if __name__ == "__main__":
unittest.main()