# Exact input and action-result contract

This file is normative for specification 0.1.0-draft.7. It defines the checks
needed to accept action evidence. A result may settle an attempt only when it
is complete, consistent under these rules, and bound to that exact attempt.
Passing these checks does not establish current authority or prove unobserved facts.

## 1. Outer input

Serialized public envelopes use 1 through 140,000 UTF-8 bytes. Byte-order marks,
UTF-16/UTF-32 auto-detection, duplicate keys, nonfinite numbers, lone Unicode
surrogates, unsupported fields and wrong shapes are rejected. The three closed
operations and inner raw-byte limits remain those in BOUNDARY.md. Whitespace
inside raw_hex retains Python bytes.fromhex semantics; identity still binds
both the exact outer bytes and the exact decoded inner request bytes.

The fixed worker verifies the outer-byte hash before decoding. The trusted
Python public-call adapter serializes its object argument in the existing
canonical UTF-8 encoding and applies the same limits before invocation. Invalid outer
input returns REJECTED_INPUT / REJECT / EZA-REQUEST-INVALID, without calling the
authority engine. A controller admission may record this input rejection;
it is not admission to the protected operation under R7. An unreadable, changed
or over-2,000,000-byte private inbox instead closes the controller UNVERIFIABLE
with no invented effect count. Valid envelopes still require full inner parsing
and current authority; accepting the envelope never grants permission.

## 2. Result shape and visible consistency

schemas/transport.schema.json describes the trusted host transport, including
a COMPLETE/null acknowledgement used only for private owner updates.
schemas/action-result.schema.json describes requester action results. COMPLETE
on an action path MUST contain its non-null record/result/handle object. A
private update acknowledgement MUST NOT settle an action admission or verify
as an action receipt. The controller and evidence schemas embed this action
schema, and the executable checker adds the cross-field equality below.

Every result must satisfy the action schema and valid Unicode/finite-value
rules. The following local consistency requirements apply:

- REJECT and ESCALATE have matching primary and blocking reasons. FAIL_SAFELY
  retains the specified objective reason and allowed underlying reason.
- NOT_EXECUTED has zero effects and a null returned value. SUCCEEDED means
  committed EXECUTE with one effect. Committed EXECUTE must be SUCCEEDED.
- Only prepared EXECUTE returns a nonempty handle. All other handles are null.
  Prepared results have no protected effect. A live handle is never a receipt.
- Every EXECUTE record, including successful preparation, has non-null request
  digest, request ID, principal, delegate, audience and authenticated actor.
  The digest has exactly the specified prefix and 64 lowercase hex characters.
  The lineage has one through eight distinct valid references. Its authenticated
  actor equals its claimed delegate. Existing schema rules govern all other fields.
- Denials may retain null or empty claims where request parsing or early binding
  checks fail. The success-only conditions MUST NOT erase truthful invalid-request
  or wrong-actor denials.

These are specified consistency checks, not a new evaluation of past grants.
Without the original request or authority state, a verifier cannot infer an
operation type from a digest, verify ownership, reconstruct lineage, test past
revocation or time, or confirm an observed value. A signature cannot fill those
missing facts. No broader proof is implied by VERIFIED_EVIDENCE_ONLY.

## 3. Binding a dispatch result

The controller's protected binding format is EZA-controller-binding/3. It pins
the outer envelope hash, actor, release and domain as before. Every admission,
every receipt ledger row and every current worker report MUST carry that same
outer request_sha256. Receipt attempt numbers must match the associated admission.
An earlier binding/2 ledger is not migrated, reset or reused by this candidate.
The authority payload format is `eza-local-object-continuity/3`; formats 1 and 2
are rejected without migration, as specified in CLOCK-HISTORY.md. Code approval
and new grant authority remain separate, and a new release cannot use an old grant.

Before accepting a current worker result or any stored receipt, check the full
action-result contract and its independently bound context:

1. An invalid outer envelope permits only REJECTED_INPUT. A valid envelope cannot
   claim REJECTED_INPUT. The decoded inner request may still be invalid.
2. COMPLETE's request_digest equals the domain-separated hash of the exact
   inner request bytes. Its authenticated actor and release match the protected
   binding. Its phase is prepared for prepare, committed for submit or commit.
3. Request ID, principal, delegate, audience and lineage equal the claims that
   are independently readable from those inner bytes. Use R10's projection:
   outside the inner byte-size range, or on failed UTF-8/JSON parsing, claims
   are empty; a decoded object retains its readable identifier claims even if
   later closed-shape or scalar checks reject it. Unreadable fields become null.
4. EXECUTE also requires the inner request's closed schema, scalar and byte limits.
   A succeeded read returns a string. A succeeded write or delete returns null.
   No validator assumes a returned string proves an actual resource read.

BLOCKED, REJECTED_INPUT and INDETERMINATE have no inner action record. Their
association comes from the trusted worker report and protected admission/receipt
wrapper, not an invented inner digest. They are not portable signed action
receipts. Fabrication of a plausible, correctly bound report by a compromised
trusted host remains outside the declared boundary.

Validate all stored receipt rows before deriving logical_outcome, including
when STOP exists. A bad record returns CLOSED_UNVERIFIABLE / UNVERIFIABLE; it
is not removed, repaired, accepted as a zero-effect result or replaced with a
new grant. A current invalid worker result is not appended as a valid receipt.
Earlier unresolved admissions remain unresolved after any valid later retry.

## 4. Shared enforcement and limits

The host's public call, fixed worker, controller and signed-claim verifier use
evaluator/result_contract.py. The signed verifier uses context-free checks plus
its independently pinned key and release; the controller and public host add
the available request binding. The evidence checker imports no authority engine,
provisioning or recovery code. Validation cannot execute a request.

If the public host cannot validate a reply after invocation, it returns
INDETERMINATE. It MUST NOT claim the invalid reply proves zero effects. The
controller exposes UNVERIFIABLE and retains its prior history. The trusted
fixture update transport is separate from these requester outcomes.

Pinned artifact hashes are read in chunks so a preserved historical archive
can exceed the small controller-record size limit. File type, link, mutation
and exact-hash checks still apply. This changes neither readable paths nor
requester permissions; controller bindings and ledgers keep their existing limits.
