Files
aios/active-runtime/app/c5_completion_renewal.py
T
AIOS Governed Continuation 540e28a724
autonomy-smoke-tests Exact governed tree; evidence 7dbba7ff168e72af
autonomy-unit-tests Exact governed tree; evidence 7dbba7ff168e72af
campaign-approval-gate Exact governed tree; evidence 7dbba7ff168e72af
git-diff-check Exact governed tree; evidence 7dbba7ff168e72af
py-compile Exact governed tree; evidence 7dbba7ff168e72af
reconciliation-contract Exact governed tree; evidence 7dbba7ff168e72af
release-state-machine Exact governed tree; evidence 7dbba7ff168e72af
secret-scan Exact governed tree; evidence 7029b3eafb209066
signer-validator-contract Exact governed tree; evidence 7dbba7ff168e72af
Publish exact C5 issuer V3 bootstrap source
2026-10-01 23:09:33 +08:00

631 lines
34 KiB
Python

"""Append-only C5 completion renewal boundary; activation requires registration.
The exact Owner-registered API, signer and completion host must call this
boundary. This module does not grant authority or perform deployment effects.
"""
import base64
import hashlib
import json
import math
import os
import stat
import time
from datetime import datetime, timezone
from pathlib import Path
from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PublicKey
from cryptography.hazmat.primitives.serialization import Encoding, PublicFormat
CID = 'rc-v2r2c5-5f65e458957d'
# Immutable release content remains compiled into the validator. Renewable
# authority identities and filesystem locations are installed only from the
# digest-bound, root-owned registration file (see configure_registered_bindings).
OLD_FP = '0' * 64
SOURCE = '5f65e458957dd51c9973cfa956a624f3cbf54990'
TREE = 'ddd239d43d63a7fbd3cff46119c71466c9443737'
ARTIFACT = '7f9d8409f07a5e0d36f5db7c55eb82ea70935fa731e057998f29cd1a5ca0a9ad'
PLAN = '370521afcf9b2288f6ad3803ca3554a46ee05d2042d53b19b4f4cb80e37a9684'
MUTABLE = {'issued_at', 'not_before', 'expires_at', 'nonce', 'fingerprint', 'signature'}
CAPABILITIES = ['baseline_registry_finalize', 'runtime_switch', 'tag_publish']
AUTHORITY_ROOT = Path('/unconfigured/c5-completion-authority')
STATE_ROOT = Path('/unconfigured/c5-completion-state')
OWNER_KEY = 'UNCONFIGURED'
TAG_OID = '6d1745ff496103db7e721a2b2bc624fda52c5dc8'
SAGA_HEAD = '0' * 64
HISTORICAL_ROOT = Path('/unconfigured/c5-completion-history')
CONTROLLER_WORKSPACE = Path('/unconfigured/c5-controller-workspace')
AUTHORITATIVE_GIT_DIR = Path('/unconfigured/c5-authoritative-git')
RUNTIME_REGISTRY_ROOT = Path('/unconfigured/c5-runtime-registry')
RUNTIME_BASELINE_PATH = Path('/unconfigured/c5-runtime-baseline.json')
TRUSTED_RELEASE_POLICY_PATH = Path('/unconfigured/c5-trusted-release-policy.json')
TRUSTED_RELEASE_POLICY_SHA256 = '0' * 64
BINDINGS_PATH_ENV = 'AIOS_C5_COMPLETION_BINDINGS_PATH'
BINDINGS_SHA256_ENV = 'AIOS_C5_COMPLETION_BINDINGS_SHA256'
_BINDINGS_DIGEST = None
RENEWAL_SOURCE_FILES = ('c5_completion_renewal.py', 'c5_release_execution_host.py',
'silent_release_hardening.py', 'c5_completion_signer.py',
'c5_completion_api.py', 'c5_completion_phase.py') # gitleaks:allow -- filenames only
PHASE_DEPENDENCIES = ('governed_tag_adapter.py', 'release_metadata_adapter.py',
'production_verification_phase_r1.py', 'public_business_acceptance_probe_r1.py',
'publisher-askpass.py', 'c5_staging_installation.py',
'aios_single_host_authority.py', 'registered_owner_signer_adapter.py')
class RenewalRejected(ValueError):
pass
def canonical(value):
return json.dumps(value, sort_keys=True, separators=(',', ':'), allow_nan=False).encode()
def digest(raw):
return hashlib.sha256(raw).hexdigest()
def validate_completion_lineage(gate):
"""Bind a current completion-only journal suffix to the frozen Saga15 head.
The suffix is authenticated by the enclosing registered Owner contract;
these checks preserve its origin and exclude deployment/source transitions.
"""
revision = gate.get('saga_revision')
suffix = gate.get('completion_journal_suffix', [])
observed = gate.get('observed_at')
if (type(revision) is not int or revision < 15 or not isinstance(suffix, list)
or type(observed) not in {int, float} or not math.isfinite(observed)):
raise RenewalRejected('COMPLETION_LINEAGE_INVALID')
if revision == 15:
if gate.get('saga_head') != SAGA_HEAD or suffix:
raise RenewalRejected('COMPLETION_LINEAGE_INVALID')
return
if not 0 < len(suffix) <= 64 or len(suffix) != revision - 15:
raise RenewalRejected('COMPLETION_LINEAGE_INVALID')
allowed = {
'owner_registered_completion_successor_tag_reconciliation': ('TAG_PENDING', {'RECONCILIATION_REQUIRED'}),
'owner_registered_tag_capability_successor_verified': ('TAG_VERIFIED', {'RECONCILIATION_REQUIRED', 'TAG_PENDING'}),
'baseline_registry_finalization_pending': ('BASELINE_REGISTRY_PENDING', {'TAG_VERIFIED'}),
'owner_registered_completion_successor_metadata_reconciliation': ('BASELINE_REGISTRY_PENDING', {'RECONCILIATION_REQUIRED'}),
'release_reconciliation_required': ('RECONCILIATION_REQUIRED', {'TAG_PENDING', 'TAG_VERIFIED', 'BASELINE_REGISTRY_PENDING'}),
}
previous, state = SAGA_HEAD, 'RECONCILIATION_REQUIRED'
for offset, event in enumerate(suffix, 16):
if (not isinstance(event, dict)
or set(event) != {'schema_version', 'sequence', 'previous_hash', 'payload', 'event_hash'}
or type(event['schema_version']) is not int or event['schema_version'] != 1
or type(event['sequence']) is not int or event['sequence'] != offset + 1
or event['previous_hash'] != previous):
raise RenewalRejected('COMPLETION_LINEAGE_INVALID')
payload = event['payload']
if (not isinstance(payload, dict)
or set(payload) != {'candidate_id', 'release_plan_id', 'revision', 'state', 'event', 'timestamp', 'details'}
or payload['candidate_id'] != CID
or payload['release_plan_id'] != 'pending-' + CID
or type(payload['revision']) is not int or payload['revision'] != offset
or not isinstance(payload['details'], dict)
or not isinstance(payload['event'], str) or payload['event'] not in allowed):
raise RenewalRejected('COMPLETION_LINEAGE_INVALID')
target, origins = allowed[payload['event']]
if payload['state'] != target or state not in origins:
raise RenewalRejected('COMPLETION_LINEAGE_INVALID')
if ('release_plan_sha256' in payload['details']
and payload['details']['release_plan_sha256'] != PLAN):
raise RenewalRejected('COMPLETION_LINEAGE_INVALID')
try:
if timestamp(payload['timestamp']) > gate['observed_at']:
raise RenewalRejected('COMPLETION_LINEAGE_INVALID')
actual = digest(canonical({key: event[key] for key in ('sequence', 'previous_hash', 'payload')}))
except (TypeError, ValueError, AttributeError, KeyError) as exc:
raise RenewalRejected('COMPLETION_LINEAGE_INVALID') from exc
if event['event_hash'] != actual:
raise RenewalRejected('COMPLETION_LINEAGE_INVALID')
previous, state = actual, target
if gate.get('saga_head') != previous:
raise RenewalRejected('COMPLETION_LINEAGE_INVALID')
def timestamp(value):
parsed = datetime.fromisoformat(value.replace('Z', '+00:00'))
if parsed.tzinfo is None or parsed.utcoffset().total_seconds() != 0:
raise RenewalRejected('UTC_REQUIRED')
return parsed.timestamp()
def verify_signature(approval, public_key):
payload = {k: v for k, v in approval.items() if k not in {'signature', 'fingerprint'}}
raw = canonical(payload)
if approval.get('fingerprint') != digest(raw):
raise RenewalRejected('APPROVAL_DIGEST_INVALID')
Ed25519PublicKey.from_public_bytes(public_key).verify(
base64.b64decode(approval['signature'], validate=True), raw
)
def validate_successor(old, new, public_key, *, now):
"""Validate historical predecessor and fresh identical-binding successor.
Historical signature verification does not authorize an expired effect.
The caller must separately verify its fresh registered Owner capability.
"""
verify_signature(old, public_key)
verify_signature(new, public_key)
exact = {'candidate_id': CID, 'source_commit': SOURCE, 'tree_oid': TREE,
'artifact_sha256': ARTIFACT, 'release_plan_sha256': PLAN,
'fingerprint': OLD_FP, 'capabilities': CAPABILITIES}
if any(old.get(k) != v for k, v in exact.items()):
raise RenewalRejected('EXACT_PREDECESSOR_REQUIRED')
if set(old) != set(new) or any(new[k] != old[k] for k in set(old) - MUTABLE):
raise RenewalRejected('IMMUTABLE_APPROVAL_BINDING_DRIFT')
if timestamp(old['expires_at']) > now:
raise RenewalRejected('PREDECESSOR_NOT_EXPIRED')
issued, not_before, expires = (timestamp(new[k]) for k in ['issued_at', 'not_before', 'expires_at'])
if not issued <= not_before <= now < expires or not 0 < expires - issued <= 900:
raise RenewalRejected('FRESH_BOUNDED_APPROVAL_REQUIRED')
if new['nonce'] == old['nonce'] or new['fingerprint'] == old['fingerprint']:
raise RenewalRejected('FRESH_APPROVAL_IDENTITY_REQUIRED')
return new['fingerprint']
def secure_bytes(path, owner_uid=0):
path = Path(path)
descriptor = os.open(path, os.O_RDONLY | os.O_NOFOLLOW)
with os.fdopen(descriptor, 'rb') as stream:
metadata = os.fstat(stream.fileno())
if not stat.S_ISREG(metadata.st_mode) or metadata.st_uid != owner_uid or metadata.st_mode & 0o022:
raise RenewalRejected('UNSAFE_RENEWAL_FILE')
return stream.read()
def _safe_parents(path):
"""Reject writable or symlinked ancestors before opening authority files."""
path = Path(path)
if not path.is_absolute() or '..' in path.parts:
raise RenewalRejected('ABSOLUTE_CANONICAL_PATH_REQUIRED')
for parent in path.parents:
info = parent.lstat()
if not stat.S_ISDIR(info.st_mode) or info.st_uid != 0 or info.st_mode & 0o022:
raise RenewalRejected('UNSAFE_AUTHORITY_ANCESTOR')
def _sha(value):
return isinstance(value, str) and len(value) == 64 and all(c in '0123456789abcdef' for c in value)
def _oid(value):
return isinstance(value, str) and len(value) == 40 and all(c in '0123456789abcdef' for c in value)
def configure_registered_bindings(path=None, expected_sha256=None, *, owner_uid=0):
"""Install renewable completion bindings from one authenticated file.
No historical approval fingerprint, Saga head, Owner key, or authority/state
path is a runtime default. The service registration must provide both the
absolute file path and its SHA-256 digest.
"""
global _BINDINGS_DIGEST
path = Path(path or os.environ.get(BINDINGS_PATH_ENV, ''))
expected_sha256 = expected_sha256 or os.environ.get(BINDINGS_SHA256_ENV, '')
if not path.is_absolute() or not _sha(expected_sha256):
raise RenewalRejected('REGISTERED_COMPLETION_BINDINGS_REQUIRED')
_safe_parents(path)
raw = secure_bytes(path, owner_uid=owner_uid)
if digest(raw) != expected_sha256:
raise RenewalRejected('COMPLETION_BINDINGS_DIGEST_MISMATCH')
if _BINDINGS_DIGEST is not None and _BINDINGS_DIGEST != expected_sha256:
raise RenewalRejected('COMPLETION_BINDINGS_REBIND_FORBIDDEN')
try:
value = json.loads(raw)
except (UnicodeDecodeError, json.JSONDecodeError) as exc:
raise RenewalRejected('COMPLETION_BINDINGS_INVALID') from exc
fields = {
'schema', 'authority_root', 'state_root', 'owner_key_id',
'predecessor_fingerprint', 'saga_head', 'historical_root',
'controller_workspace', 'authoritative_git_dir',
'runtime_registry_root', 'runtime_baseline_path',
'trusted_release_policy_path', 'trusted_release_policy_sha256',
}
if not isinstance(value, dict) or set(value) != fields or value.get('schema') != 'aios.c5.completion-bindings.v1':
raise RenewalRejected('COMPLETION_BINDINGS_SCHEMA_INVALID')
authority_root = Path(value['authority_root'])
state_root = Path(value['state_root'])
governed_paths = {
name: Path(value[name]) for name in (
'historical_root', 'controller_workspace', 'authoritative_git_dir',
'runtime_registry_root', 'runtime_baseline_path', 'trusted_release_policy_path',
)
}
owner_key_id = value['owner_key_id']
try:
owner_key_valid = (isinstance(owner_key_id, str)
and owner_key_id.startswith('SHA256:')
and len(base64.b64decode(owner_key_id[7:], validate=True)) == 32)
except (ValueError, TypeError):
owner_key_valid = False
all_paths = (authority_root, state_root, *governed_paths.values())
if (any(not item.is_absolute() or '..' in item.parts for item in all_paths)
or not _sha(value['predecessor_fingerprint']) or not _sha(value['saga_head'])
or not _sha(value['trusted_release_policy_sha256'])
or not owner_key_valid):
raise RenewalRejected('COMPLETION_BINDINGS_VALUE_INVALID')
if path.parent != authority_root:
raise RenewalRejected('COMPLETION_BINDINGS_ROOT_MISMATCH')
global AUTHORITY_ROOT, STATE_ROOT, OWNER_KEY, OLD_FP, SAGA_HEAD
global HISTORICAL_ROOT, CONTROLLER_WORKSPACE, AUTHORITATIVE_GIT_DIR
global RUNTIME_REGISTRY_ROOT, RUNTIME_BASELINE_PATH
global TRUSTED_RELEASE_POLICY_PATH, TRUSTED_RELEASE_POLICY_SHA256
AUTHORITY_ROOT = authority_root
STATE_ROOT = state_root
OWNER_KEY = value['owner_key_id']
OLD_FP = value['predecessor_fingerprint']
SAGA_HEAD = value['saga_head']
HISTORICAL_ROOT = governed_paths['historical_root']
CONTROLLER_WORKSPACE = governed_paths['controller_workspace']
AUTHORITATIVE_GIT_DIR = governed_paths['authoritative_git_dir']
RUNTIME_REGISTRY_ROOT = governed_paths['runtime_registry_root']
RUNTIME_BASELINE_PATH = governed_paths['runtime_baseline_path']
TRUSTED_RELEASE_POLICY_PATH = governed_paths['trusted_release_policy_path']
TRUSTED_RELEASE_POLICY_SHA256 = value['trusted_release_policy_sha256']
_BINDINGS_DIGEST = expected_sha256
return dict(value)
class RegisteredCompletionAuthority:
"""Fixed root registration, Owner signature and immutable evidence verifier.
The completed production proofs are historical facts. This fresh authority
permits only approval renewal and remaining metadata effects; it cannot
authorize another runtime switch or public acceptance Task.
"""
@property
def root(self):
return AUTHORITY_ROOT
@property
def state_root(self):
return STATE_ROOT
def __call__(self):
from c5_staging_installation import RegistryOwnerVerifier
root = AUTHORITY_ROOT
_safe_parents(root / 'contract.json')
envelope = json.loads(secure_bytes(root / 'contract.json'))
if set(envelope) != {'payload', 'signature'}:
raise RenewalRejected('EXACT_AUTHORITY_ENVELOPE_REQUIRED')
p = envelope['payload']
fields = {'schema', 'host', 'repository', 'candidate_id', 'source_commit', 'tree_oid',
'artifact_sha256', 'release_plan_sha256', 'state_root', 'predecessor_fingerprint',
'predecessor_sha256', 'predecessor_uid', 'predecessor_snapshot', 'approval_nonce',
'issued_at', 'expires_at', 'owner_key_id', 'owner_namespace', 'allowed_effects',
'runtime_effects_allowed', 'files', 'gate_path', 'gate_observed_at',
'governed_source_commit', 'governed_source_tree'}
if not isinstance(p, dict) or set(p) != fields:
raise RenewalRejected('EXACT_AUTHORITY_SCHEMA_REQUIRED')
exact = {'schema': 'aios.c5.registered-completion-authority.v1', 'host': 'cn-network-mkt',
'repository': 'aios/aios', 'candidate_id': CID, 'source_commit': SOURCE,
'tree_oid': TREE, 'artifact_sha256': ARTIFACT, 'release_plan_sha256': PLAN,
'state_root': str(STATE_ROOT), 'predecessor_fingerprint': OLD_FP,
'owner_key_id': OWNER_KEY, 'owner_namespace': 'aios-owner-approval-v1',
'allowed_effects': ['approval_successor_append', 'baseline_finalize', 'registry_finalize', 'tag_publish'],
'runtime_effects_allowed': False}
if any(p[k] != v for k, v in exact.items()) or type(p['runtime_effects_allowed']) is not bool:
raise RenewalRejected('EXACT_COMPLETION_AUTHORITY_REQUIRED')
now = time.time()
if (type(p['issued_at']) is not int or type(p['expires_at']) is not int
or not p['issued_at'] <= now < p['expires_at']
or not 0 < p['expires_at'] - p['issued_at'] <= 1800
or type(p['gate_observed_at']) not in {int, float}
or not math.isfinite(p['gate_observed_at'])
or not p['issued_at'] - 60 <= p['gate_observed_at'] <= p['issued_at']):
raise RenewalRejected('FRESH_OWNER_AUTHORITY_REQUIRED')
if (not _sha(p['approval_nonce']) or not _sha(p['predecessor_sha256'])
or type(p['predecessor_uid']) is not int or p['predecessor_uid'] not in {0, 1000}
or any(not isinstance(p[k], str) or len(p[k]) != 40
or any(c not in '0123456789abcdef' for c in p[k])
for k in ('governed_source_commit', 'governed_source_tree'))):
raise RenewalRejected('AUTHORITY_IDENTITIES_INVALID')
verifier = RegistryOwnerVerifier(Path('/etc/aios/single-host-signer-registry.json'),
owner_signer_id='local-owner-authority')
if not verifier.verify(namespace=p['owner_namespace'], payload=canonical(p),
signature=envelope['signature'], key_id=p['owner_key_id']):
raise RenewalRejected('OWNER_SIGNATURE_REJECTED')
payload_sha = digest(canonical(p))
registered = json.loads(secure_bytes(root / 'registration.json'))
if (set(registered) != {'schema', 'status', 'payload_sha256', 'approval_nonce'}
or registered != {'schema': 'aios.c5.completion-registration.v1', 'status': 'REGISTERED',
'payload_sha256': payload_sha, 'approval_nonce': p['approval_nonce']}):
raise RenewalRejected('ROOT_REGISTRATION_REQUIRED')
if (root / 'rollback.json').exists():
raise RenewalRejected('REGISTRATION_ROLLED_BACK')
pins = p['files']
if not isinstance(pins, list) or not pins:
raise RenewalRejected('SIGNED_FILE_CLOSURE_REQUIRED')
checked = {}
for item in pins:
if (not isinstance(item, dict) or set(item) != {'path', 'sha256', 'uid'}
or not _sha(item['sha256']) or type(item['uid']) is not int or item['uid'] != 0):
raise RenewalRejected('SIGNED_FILE_PIN_INVALID')
path = Path(item['path'])
if path.parent != root or str(path) in checked:
raise RenewalRejected('SIGNED_FILE_PATH_INVALID')
_safe_parents(path)
raw = secure_bytes(path)
if digest(raw) != item['sha256']:
raise RenewalRejected('SIGNED_FILE_BYTES_DRIFT')
checked[str(path)] = raw
required = {str(root / name) for name in (*RENEWAL_SOURCE_FILES, *PHASE_DEPENDENCIES, 'source-material.json',
'historical-production-proof.json', 'predecessor-approval.json', 'current-gate.json',
'approval-public-keyring.json', 'original_api.py')}
if not required <= set(checked):
raise RenewalRejected('INCOMPLETE_REGISTERED_CLOSURE')
if Path(__file__) != root / 'c5_completion_renewal.py':
raise RenewalRejected('UNREGISTERED_AUTHORITY_MODULE')
if (p['predecessor_snapshot'] != str(root / 'predecessor-approval.json')
or p['gate_path'] != str(root / 'current-gate.json')
or digest(checked[p['predecessor_snapshot']]) != p['predecessor_sha256']):
raise RenewalRejected('REGISTERED_SNAPSHOT_DRIFT')
material = json.loads(checked[str(root / 'source-material.json')])
if (material.get('status') != 'MATERIALIZED' or material.get('task_status') != 'SUCCEEDED'
or material.get('remote_verified') is not True
or material.get('source_commit') != p['governed_source_commit']
or material.get('source_tree') != p['governed_source_tree']
or material.get('file_sha256') != {
name: digest(checked[str(root / name)])
for name in RENEWAL_SOURCE_FILES}):
raise RenewalRejected('GOVERNED_CODE_PROVENANCE_REQUIRED')
historical = json.loads(checked[str(root / 'historical-production-proof.json')])
if (historical.get('candidate_id') != CID or historical.get('approval_fingerprint') != OLD_FP
or historical.get('release_plan_sha256') != PLAN
or historical.get('status') != 'COMPLETED'
or any(historical.get(k) is not True for k in (
'public_business_verified', 'real_c4_rollback_verified', 'c5_restore_verified'))):
raise RenewalRejected('COMPLETED_PRODUCTION_PROOF_REQUIRED')
gate = json.loads(checked[p['gate_path']])
expected_gate = {'candidate_id': CID, 'source_commit': SOURCE, 'artifact_sha256': ARTIFACT,
'release_plan_sha256': PLAN,
'local_tag_oid': TAG_OID, 'runtime_verified': True, 'business_verified': True,
'global_writes_enabled': False, 'observed_at': p['gate_observed_at']}
if (any(gate.get(k) != v for k, v in expected_gate.items())
or any(type(gate.get(k)) is not bool for k in (
'runtime_verified', 'business_verified', 'global_writes_enabled'))
or gate.get('remote_tag_oid') not in {None, TAG_OID}):
raise RenewalRejected('EXACT_POSTVERIFICATION_GATE_REQUIRED')
validate_completion_lineage(gate)
return {**p, 'payload_sha256': payload_sha}
def validate_host(self, *, state_root, candidate_id, source_commit, tree_oid,
artifact_sha256, release_plan_sha256):
self()
if (Path(state_root), candidate_id, source_commit, tree_oid, artifact_sha256, release_plan_sha256) != (
STATE_ROOT, CID, SOURCE, TREE, ARTIFACT, PLAN):
raise RenewalRejected('COMPLETION_HOST_BINDING_DRIFT')
def deny_runtime_effect(self, **kwargs):
self()
raise RenewalRejected('COMPLETION_RUNTIME_EFFECT_FORBIDDEN')
class CompletionRuntimeGuard:
def __init__(self, authority):
if type(authority) is not RegisteredCompletionAuthority:
raise RenewalRejected('REGISTERED_COMPLETION_AUTHORITY_REQUIRED')
self.authority = authority
def execute(self, **kwargs):
return self.authority.deny_runtime_effect(**kwargs)
def append_file(path, raw):
"""An existing record must be identical; it is never replaced."""
path = Path(path)
try:
fd = os.open(path, os.O_WRONLY | os.O_CREAT | os.O_EXCL | os.O_NOFOLLOW, 0o600)
except FileExistsError:
if secure_bytes(path, owner_uid=os.geteuid()) != raw:
raise RenewalRejected('APPEND_ONLY_RECORD_CONFLICT')
return False
with os.fdopen(fd, 'wb') as stream:
stream.write(raw)
stream.flush()
os.fsync(stream.fileno())
fd = os.open(path.parent, os.O_DIRECTORY)
try:
os.fsync(fd)
finally:
os.close(fd)
return True
def publish_successor(directory, old, new, public_key, *, now, registration_digest, predecessor_bytes):
"""Append records inside the SAME plane under a verified caller lock.
Registration validation, current Saga CAS, production/business readbacks,
and permission to call this function remain mandatory caller gates.
"""
fp = validate_successor(old, new, public_key, now=now)
if json.loads(predecessor_bytes) != old:
raise RenewalRejected('PREDECESSOR_BYTES_DRIFT')
predecessor_bytes_digest = digest(predecessor_bytes)
if len(registration_digest) != 64 or any(c not in '0123456789abcdef' for c in registration_digest):
raise RenewalRejected('REGISTERED_DIGEST_REQUIRED')
directory = Path(directory)
metadata = directory.lstat()
if not stat.S_ISDIR(metadata.st_mode) or metadata.st_uid != os.geteuid() or metadata.st_mode & 0o022:
raise RenewalRejected('UNSAFE_APPEND_DIRECTORY')
receipt = {'schema': 'aios.c5.completion-approval-successor.v1', 'candidate_id': CID,
'predecessor_fingerprint': OLD_FP, 'predecessor_bytes_sha256': predecessor_bytes_digest,
'successor_fingerprint': fp, 'successor_sha256': digest(canonical(new)),
'owner_registration_payload_sha256': registration_digest,
'completion_only': True, 'runtime_effects_allowed': False}
# A crash after the first append is unresolved until its exact receipt is
# reconciled. A loader must require BOTH files; no mutable current pointer.
append_file(directory / (fp + '.approval.json'), canonical(new))
append_file(directory / (fp + '.receipt.json'), canonical(receipt))
return receipt
class CompletionApprovalStore:
"""Explicit store dependency for a registered completion host/API.
The original store and original candidate approval remain untouched.
No global class replacement or expired approval verification is used.
An authenticated registration fixes ONE successor nonce and immutable
receipt path before signing. The host must separately enforce TAG_PENDING
and forbid runtime effects; this store does not execute a Saga.
"""
def __init__(self, original, directory, public_key, authority, approval_type):
self.original = original
self.directory = Path(directory)
self.public_key = public_key
self.authority = authority
self.approval_type = approval_type
def _policy(self):
# authority must be the fixed registered verifier, not a caller-supplied
# HTTP callback. Wiring it is outside this unregistered draft.
policy = self.authority()
if policy.get('candidate_id') != CID or policy.get('predecessor_fingerprint') != OLD_FP:
raise RenewalRejected('REGISTERED_EXACT_POLICY_REQUIRED')
nonce = policy.get('approval_nonce', '')
if not isinstance(nonce, str) or len(nonce) != 64 or any(c not in '0123456789abcdef' for c in nonce):
raise RenewalRejected('REGISTERED_NONCE_REQUIRED')
return policy, self.directory / (nonce + '.activation.json')
def _parent(self):
old = self.original.load(CID)
policy, _ = self._policy()
owner = policy.get('predecessor_uid')
if type(owner) is not int or owner not in {0, 1000}:
raise RenewalRejected('REGISTERED_PREDECESSOR_OWNER_REQUIRED')
raw = secure_bytes(self.original.root / (CID + '.json'), owner_uid=owner)
if json.loads(raw) != old.to_dict() or digest(raw) != policy.get('predecessor_sha256'):
raise RenewalRejected('PREDECESSOR_FILE_DRIFT')
return old.to_dict(), raw
def load(self, candidate_id):
if candidate_id != CID:
return self.original.load(candidate_id)
policy, activation = self._policy()
if not activation.exists():
return self.original.load(candidate_id)
receipt = json.loads(secure_bytes(activation, owner_uid=policy['predecessor_uid']))
expected = {'schema', 'candidate_id', 'predecessor_fingerprint', 'predecessor_bytes_sha256',
'successor_fingerprint', 'successor_sha256', 'owner_registration_payload_sha256',
'completion_only', 'runtime_effects_allowed'}
if set(receipt) != expected or receipt.get('owner_registration_payload_sha256') != policy['payload_sha256']:
raise RenewalRejected('ACTIVATION_RECEIPT_INVALID')
fp = receipt.get('successor_fingerprint', '')
if len(fp) != 64 or any(c not in '0123456789abcdef' for c in fp):
raise RenewalRejected('SUCCESSOR_FINGERPRINT_INVALID')
raw = secure_bytes(self.directory / (fp + '.approval.json'), owner_uid=policy['predecessor_uid'])
new = json.loads(raw)
parent, parent_raw = self._parent()
valid = validate_successor(parent, new, self.public_key, now=datetime.now(timezone.utc).timestamp())
exact = {'candidate_id': CID, 'predecessor_fingerprint': OLD_FP,
'predecessor_bytes_sha256': digest(parent_raw), 'successor_fingerprint': valid,
'successor_sha256': digest(raw), 'completion_only': True, 'runtime_effects_allowed': False}
if any(receipt.get(k) != v for k, v in exact.items()) or new['nonce'] != policy['approval_nonce']:
raise RenewalRejected('SUCCESSOR_ACTIVATION_DRIFT')
durable = json.loads(secure_bytes(self.directory / (fp + '.receipt.json'), owner_uid=policy['predecessor_uid']))
if durable != receipt:
raise RenewalRejected('DURABLE_RECEIPT_DRIFT')
return self.approval_type.from_dict(new)
def save(self, candidate_id, approval):
if candidate_id != CID:
return self.original.save(candidate_id, approval)
policy, activation = self._policy()
parent, raw = self._parent()
if approval.fingerprint == parent['fingerprint']:
return self.original.save(candidate_id, approval)
new = approval.to_dict()
if new.get('nonce') != policy['approval_nonce']:
raise RenewalRejected('REGISTERED_NONCE_MISMATCH')
# The caller supplies its authenticated registered effect lock and
# invokes the existing ApprovalVerifier before this store boundary.
receipt = publish_successor(self.directory, parent, new, self.public_key,
now=datetime.now(timezone.utc).timestamp(),
registration_digest=policy['payload_sha256'], predecessor_bytes=raw)
created = append_file(activation, canonical(receipt))
if self.load(candidate_id).fingerprint != approval.fingerprint:
raise RenewalRejected('SUCCESSOR_READBACK_FAILED')
return activation, created
class RegisteredCompletionApprovalStore(CompletionApprovalStore):
"""Production dependency; no request-selected root or authority callback."""
def __init__(self, original, public_key, approval_type):
if Path(original.root) != STATE_ROOT / 'approvals':
raise RenewalRejected('SAME_APPROVAL_PLANE_REQUIRED')
super().__init__(original, STATE_ROOT / 'approvals' / 'c5-completion-successors',
public_key, RegisteredCompletionAuthority(), approval_type)
class CompletionSignerMixin:
"""Narrow additional method of the EXISTING credential-bound signer.
Activation must register this exact mixin, verifier and namespace snapshot
pins. The encrypted private key stays in the existing signer's unit. This
draft supplies no activation, credential access or HTTP route.
"""
def sign_exact_completion_successor(self, request):
expected = {'schema', 'operation', 'candidate_id', 'predecessor_fingerprint'}
if (set(request) != expected or request.get('operation') != 'renew_exact_completion_approval'
or request.get('candidate_id') != CID or request.get('predecessor_fingerprint') != OLD_FP
or request.get('schema') != 'aios.exact-release-signer.request.v1'):
raise RenewalRejected('EXACT_SIGNER_RENEWAL_REQUEST_REQUIRED')
policy = self.completion_authority()
now = datetime.now(timezone.utc).timestamp()
if (policy.get('candidate_id') != CID or policy.get('predecessor_fingerprint') != OLD_FP
or not policy['issued_at'] <= now < policy['expires_at']
or not 0 <= now - policy['gate_observed_at'] <= 60):
raise RenewalRejected('FRESH_REGISTERED_COMPLETION_GATE_REQUIRED')
old_raw = secure_bytes(policy['predecessor_snapshot'], owner_uid=0)
if digest(old_raw) != policy['predecessor_sha256']:
raise RenewalRejected('REGISTERED_SIGNER_PREIMAGE_DRIFT')
old = json.loads(old_raw)
public_key = self.private_key.public_key().public_bytes(Encoding.Raw, PublicFormat.Raw)
verify_signature(old, public_key)
exact = {'candidate_id': CID, 'source_commit': SOURCE, 'tree_oid': TREE,
'artifact_sha256': ARTIFACT, 'release_plan_sha256': PLAN,
'fingerprint': OLD_FP, 'capabilities': CAPABILITIES,
'key_id': self.policy.key_id, 'owner_identity': self.policy.owner_identity,
'trust_domain': self.policy.trust_domain,
'owner_approval_record_oid': self.authorization_oid}
if any(old.get(k) != v for k, v in exact.items()) or timestamp(old['expires_at']) > now:
raise RenewalRejected('EXACT_EXPIRED_SIGNER_PREDECESSOR_REQUIRED')
nonce = policy['approval_nonce']
if len(nonce) != 64 or any(c not in '0123456789abcdef' for c in nonce) or nonce == old['nonce']:
raise RenewalRejected('FRESH_REGISTERED_SIGNER_NONCE_REQUIRED')
output = self.state_root / 'completion-renewals' / (nonce + '.json')
if output.exists():
result = json.loads(secure_bytes(output, owner_uid=0))
if (result.get('registration_payload_sha256') != policy['payload_sha256']
or result['approval']['nonce'] != nonce):
raise RenewalRejected('SIGNER_REPLAY_CONFLICT')
validate_successor(old, result['approval'], public_key, now=now)
return {**result, 'status': 'SIGNED_IDEMPOTENT'}
expiry = min(now + 600, policy['expires_at'] - 5)
if expiry - now < 120:
raise RenewalRejected('INSUFFICIENT_SIGNER_WINDOW')
def utc(value):
return datetime.fromtimestamp(value, timezone.utc).replace(microsecond=0).isoformat().replace('+00:00', 'Z')
payload = {k:v for k,v in old.items() if k not in {'fingerprint', 'signature'}}
payload.update(issued_at=utc(now), not_before=utc(now), expires_at=utc(expiry), nonce=nonce)
raw = canonical(payload)
# All candidate, plan, historical signature and registered freshness
# checks precede this only signing operation.
approval = {**payload, 'fingerprint': digest(raw),
'signature': base64.b64encode(self.private_key.sign(raw)).decode()}
validate_successor(old, approval, public_key, now=now)
result = {'schema': 'aios.exact-release-signer.response.v1', 'status': 'SIGNED',
'approval': approval, 'registration_payload_sha256': policy['payload_sha256'],
'predecessor_fingerprint': OLD_FP, 'completion_only': True, 'arbitrary_signing': False}
# This registered directory must be created by the activation consumer
# inside the existing signer state root, never a request path.
append_file(output, canonical(result))
return result