Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
180 changes: 180 additions & 0 deletions .getzilla/getzilla/model_data_admission.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
"""Bind an offline request preview; never authorize a model data transfer.

The supplied account reference is an unverified label. This module does not
read credentials, validate human consent, or provide a dispatch capability.
"""
from __future__ import annotations

import hashlib
import json
import re
import time
from dataclasses import asdict, dataclass, replace
from pathlib import Path

from . import model_continuation_state as journal
from . import openai_model_request as requests

_HANDLE = re.compile(r'[A-Za-z0-9][A-Za-z0-9._-]{0,63}\Z')
_ENDPOINT = 'https://api.openai.com/v1/responses'
_MAX_REQUEST_BYTES = 4_000_000


class AdmissionError(ValueError):
"""Fixed diagnostic code with no payload or credential data."""


@dataclass(frozen=True, repr=False)
class AccountReference:
provider: str
account_ref: str
handle: str
version: str


@dataclass(frozen=True, repr=False)
class AccountResolution:
reference: AccountReference

@property
def account_identity_verified(self) -> bool:
return False


def _valid_account(account) -> bool:
if type(account) is not AccountReference:
return False
values = (account.provider, account.account_ref, account.handle, account.version)
return all(type(value) is str and _HANDLE.fullmatch(value)
and not value.lower().startswith('sk-') for value in values)


def resolve_account(provider: str, account_ref: str, records: tuple) -> AccountResolution:
"""Resolve a unique metadata mapping, without asserting credential ownership."""
if type(records) is not tuple or not 1 <= len(records) <= 64 or any(not _valid_account(r) for r in records):
raise AdmissionError('account_mapping_invalid')
matches = [r for r in records if r.provider == provider and r.account_ref == account_ref]
if len(matches) != 1:
raise AdmissionError('account_mapping_ambiguous')
return AccountResolution(matches[0])


@dataclass(frozen=True, repr=False)
class Preview:
root_digest: str
binding_digest: str
contract_digest: str
policy_digest: str
request_digest: str
request_bytes: int
account_digest: str
generation: int
revision: int
issued_epoch: int
expires_epoch: int
endpoint: str = _ENDPOINT
preview_digest: str = ''


def _preview_digest(preview: Preview) -> str:
# An unkeyed consistency checksum, not a signature or authorization token.
value = asdict(preview)
del value['preview_digest']
return journal._digest(value)


def _now() -> int:
try:
value = time.time()
if type(value) not in (int, float) or not 1 <= value <= journal.MAX_EPOCH_SECONDS:
raise AdmissionError('clock_uncertain')
return int(value)
except (OSError, TypeError, ValueError, OverflowError):
raise AdmissionError('clock_uncertain') from None


def _checked(root: Path, binding, contract, request, account, generation, revision, expires_epoch, now):
if not _valid_account(account):
raise AdmissionError('invalid_account_reference')
if type(generation) is not int or not 0 < generation <= 64:
raise AdmissionError('invalid_generation')
if not journal._integer(revision):
raise AdmissionError('invalid_revision')
if type(expires_epoch) is not int or not 0 < expires_epoch <= journal.MAX_EPOCH_SECONDS:
raise AdmissionError('invalid_expiry')
try:
directory = journal.fsx.open_dir(root)
try:
root_info = journal.fsx.fstat_dir(directory)
root_digest = journal._digest([root_info.st_dev, root_info.st_ino])
finally:
journal.fsx.close_dir(directory)
policy, policy_digest = journal._policy(root)
bound = journal._binding(binding)
if type(contract) is not requests.Contract or type(request) is not requests.PreparedRequest:
raise AdmissionError('invalid_request')
if (type(request.body) is not bytes or len(request.body) > _MAX_REQUEST_BYTES
or type(request.reserved_cost_micros) is not int):
raise AdmissionError('invalid_request')
data = json.loads(request.body)
if not isinstance(data, dict) or set(data) != {'input', 'model', 'max_output_tokens', 'store'}:
raise AdmissionError('invalid_request')
checked = requests.prepare(contract, data['input'])
if checked.body != request.body or checked.reserved_cost_micros != request.reserved_cost_micros:
raise AdmissionError('invalid_request')
if generation > len(policy.candidates):
raise AdmissionError('candidate_denied')
candidate = policy.candidates[generation - 1]
if (candidate.provider != 'openai' or candidate.provider != account.provider
or candidate.account_ref != account.account_ref or contract.account_ref != account.account_ref
or candidate.model != contract.model):
raise AdmissionError('candidate_denied')
if (now >= expires_epoch or expires_epoch > contract.expires_epoch
or expires_epoch > now + int(policy.bounds.deadline_seconds)):
raise AdmissionError('expired_or_unbounded')
directory = journal.fsx.open_dir(root)
try:
after = journal.fsx.fstat_dir(directory)
if (after.st_dev, after.st_ino) != (root_info.st_dev, root_info.st_ino):
raise AdmissionError('root_changed')
finally:
journal.fsx.close_dir(directory)
return (root_digest, journal._digest(bound), journal._digest(asdict(contract)), policy_digest,
hashlib.sha256(request.body).hexdigest(), len(request.body), journal._digest(asdict(account)))
except (journal.JournalError, requests.RequestError, OSError, KeyError, TypeError, ValueError, UnicodeError, RecursionError):
raise AdmissionError('preflight_denied') from None


def prepare_preview(root: Path, binding, contract, request, account, generation: int,
expires_epoch: int, *, revision: int) -> Preview:
"""Capture references for review; generation/revision are not journal claims."""
now = _now()
values = _checked(root, binding, contract, request, account, generation, revision, expires_epoch, now)
preview = Preview(*values, generation, revision, now, expires_epoch)
return replace(preview, preview_digest=_preview_digest(preview))


def recheck_preview(root: Path, preview, binding, contract, request, account, generation: int, *, revision: int) -> dict:
"""Recheck this private observation; success never permits dispatch."""
if (type(preview) is not Preview or type(preview.endpoint) is not str or preview.endpoint != _ENDPOINT
or any(not journal._integer(v, journal.MAX_EPOCH_SECONDS)
for v in (preview.issued_epoch, preview.expires_epoch))
or not journal._integer(preview.generation, 64)
or not journal._integer(preview.request_bytes, _MAX_REQUEST_BYTES)
or not journal._integer(preview.revision)
or preview.issued_epoch >= preview.expires_epoch
or any(type(v) is not str or not re.fullmatch(r'[a-f0-9]{64}', v)
for v in (preview.root_digest, preview.binding_digest, preview.contract_digest, preview.policy_digest,
preview.request_digest, preview.account_digest, preview.preview_digest))):
raise AdmissionError('invalid_preview')
if _preview_digest(preview) != preview.preview_digest:
raise AdmissionError('preview_changed')
now = _now()
if now < preview.issued_epoch or now >= preview.expires_epoch:
raise AdmissionError('expired_or_clock_uncertain')
values = _checked(root, binding, contract, request, account, generation, revision, preview.expires_epoch, now)
expected = (preview.root_digest, preview.binding_digest, preview.contract_digest, preview.policy_digest,
preview.request_digest, preview.request_bytes, preview.account_digest)
if values != expected or generation != preview.generation or revision != preview.revision:
raise AdmissionError('preview_changed')
return {'state': 'ready_for_review', 'dispatch_permitted': False, 'account_identity_verified': False}
1 change: 1 addition & 0 deletions architecture/system.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2209,6 +2209,7 @@
".codex",
".gemini",
".getzilla/getzilla",
".getzilla/getzilla/model_data_admission.py",
".getzilla/templates",
".grok",
".qwen"
Expand Down
10 changes: 10 additions & 0 deletions docs/model-continuation-journal.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ The optional `codex_continuation.start_offline_container` entry point starts the

Disable the policy to stop reservation. Preserve the journal and unknown outcomes. Revert source through a reviewed PR if needed; never delete a ledger to regain attempts or money. No live dispatch path exists to roll back in T3.

## Offline exact-request preview

`getzilla.model_data_admission` provides an in-memory, non-authorizing preview. It reuses `openai_model_request.prepare` to check the exact canonical text-only request. It binds the request bytes and length, fixed `https://api.openai.com/v1/responses` destination, account reference/handle/version metadata, contract, policy, existing `Binding`, caller-supplied candidate generation and journal revision, observed root-directory identity, issue time and expiry. Rechecking refuses changed fields, expiry, backward clock observations, invalid clocks and revoked policy. Errors and status contain fixed codes, not request text or account handles.

The four account-reference fields and preview endpoint/digest fields must be built-in strings. Account validation checks those fields directly; it rejects containers and string subclasses before copying. Preview recheck rejects string subclasses before computing its consistency checksum.

The result is only `ready_for_review`, with `dispatch_permitted:false` and `account_identity_verified:false`. The unique account-metadata mapping does not verify credential ownership. Task/source/checkpoint digests and generation/revision are caller references, not current source, journal, grant or native-provenance evidence. The private preview checksum detects independent field changes but is unkeyed and reproducible; it proves no authenticity or consent. Root identity is a point-in-time directory observation, not a complete workspace snapshot or lock. The request digest can disclose low-entropy input through guessing, so keep the preview and its digests private.

This helper reads no credential, opens no provider connection, creates no grant or accounting claim, and changes no journal or metrics record. `openai_model_request.dispatch` still raises `data_admission_unavailable` before claim consumption. Later live work must reuse the existing grants, source inventory, secret scanning and journal contracts to establish exact payload/source-audience permission, recipient/account ownership, current revocation checks and one qualified runtime row. A scanner result or this preview cannot supply those facts. All live adapter rows remain unqualified and issue235 remains open. Roll back this helper through a reviewed revert; the existing dispatch refusal remains in force.

## Controlled local fixture

`getzilla.controlled_fixture.run` exercises only a synthetic two-model Codex session. It requires a pinned local Docker image and an exact Codex 0.165.0 binary. The image is not downloaded. The host copies the fixture script and binary into a new local image and verifies both hashes inside that image before use. The inspected execution container has no bind mounts. It uses `network=none`, read-only root, a non-root user, dropped capabilities and bounded resources. It receives no host journal, credentials or user input. This assumes the local Docker daemon and pinned base image are trusted.
Expand Down
Loading
Loading