# Exact-action review binding v1

**Status:** OpenVerifier v13.9.0-rc3. Independently operated verifier-side profile.
Current package review/deployment state is external to these immutable verification bytes.
This is not an EMILIA native Gate export, certification, or execution API.

The exact-action profile was independently rerun in rc2, and that rc2 production
surface was separately checked byte-for-byte under a secure browser origin. This
completed rc3 candidate retains the same exact-action decision/check rules while
finishing UI/state/reporting/onboarding and release-state separation. Mutable
package-review state is not emitted in verification results. Current rc3
review/deployment state is external to these immutable package bytes. The prior
rc2 deployment record is hash-identified but unsigned.

## The invariant

Under explicit relying-party trust pins, verify the original SYNC receipt under
its native signing rules; prove that its signed intent designates a particular
sealed review packet; recompute CAID from the exact typed action in that packet;
require Gate to reference the exact original SYNC receipt bytes; and require
that reviewed action to equal the action in Gate's admitted record.

**SYNC records what the person reviewed; Gate decides whether that exact action
may cross. Neither alone proves what happened afterward.**

The new result is a historical evidence assessment. `MATCH` never authorizes a
new action, consumes authority, invokes a provider, or reconciles an outcome.

## Exact-action continuity — explanatory term

OpenVerifier uses **exact-action continuity** as plain-language shorthand for the
relationship established when the material action protected by the human-reviewed
SYNC record is independently shown to be the same typed action represented by the
corresponding signed Gate compatibility projection. It is not an additional
protocol state or a new authorization decision. A continuity match does not prove
that Gate executed the action, that a provider committed it, or that a physical
effect occurred.

## Deliberately narrow supported inputs

- SYNC full **VC JSON** with type `SYNCAuthorizationReceipt` and the shipping
  `sync.intent_evidence_payload.current.v1` signed-payload profile.
- A canonical reviewed-action packet described below, attached before sealing.
- The unchanged `OPENVERIFIER-EMILIA-GATE-PROJECTION-v3` compatibility projection
  containing its exact SYNC receipt-byte attachment.
- The bundled, pinned `payment.release.1` registry-v3 definition, including a
  closed verifier-local ISO 4217 alpha-3 membership pin in
  `spec/ISO_4217_ALPHA3_PIN_v1.json`. Other action
  types are refused; there is no generic semantic mapping or implicit registry
  update in this candidate.
- A separate relying-party context. The bundle cannot provide its own trust pins.

Receipt-only VC-JWT, compact JWT, raw technical JSON, and Local W3C package
viewing remain in the original UI. They do not silently inherit this new binding
assessment. Export **full VC JSON** for the new exact-action review.

## 1. Prepare the reviewed-action packet

The packet has exactly four fields:

```json
{
  "profile": "OPENVERIFIER-REVIEWED-ACTION-v1",
  "purpose": "human_review_for_gate_admission",
  "scope": {
    "tenant_id": "customer-tenant",
    "operation_id": "operation-identifier",
    "principal_authority_ref": "authority-reference"
  },
  "action": {
    "caid": "caid:1:payment.release.1:jcs-sha256:<recomputed-base64url>",
    "digest": "sha256:<recomputed-hex>",
    "object": {
      "action_type": "payment.release.1",
      "amount": "4500.00",
      "currency": "USD",
      "beneficiary_account": "sha256:<64-lowercase-hex>",
      "payment_instruction_id": "instruction-identifier"
    }
  }
}
```

The example above is explanatory, not a valid signed fixture. The preparation
tool produces real digests and canonical UTF-8 bytes, with sorted object keys,
no byte-order mark, no whitespace outside strings, and no trailing newline.
The action uses the existing pinned CAID canonicalization and material-schema
checks. The **packet digest and the action digest are different commitments**:
the packet also protects its purpose and operation scope.

The packet's SHA-256 must occur **exactly once** in the signed native evidence
list. The signed evidence entry must have the correct byte length and explicit
`sealedBeforeAuthorization: true`. Filenames are descriptive, not identity.

## 2. Designate that packet in signed intent

Evidence inclusion alone can mean background material, alternatives, or even a
rejected proposal. It must not be promoted into an affirmative review claim.
This first profile therefore uses one exact, generated intent statement:

```text
I reviewed the exact action in the attached OpenVerifier review packet for the operation it identifies.
Review packet SHA-256: <64 lowercase hex of the exact packet bytes>
```

There is one LF between lines and no trailing newline. The preparation tool
writes the text to paste into the **existing** SYNC intent field. The user
reviews the complete action/scope, attaches `reviewed-action.json`, pastes this
statement, seals normally, and exports full VC JSON. No iOS source, receipt
schema, key, or device ceremony is changed.

This statement records a review acknowledgment. It is not a universal `PERMIT`,
organizational authorization decision, or proof that the human understood what
was shown. The Gate owner still decides whether the action may cross.

A receipt created without this designated packet cannot be upgraded by adding
an unsigned sidecar afterward. A fresh review/seal is required.

## 3. Verify the native SYNC seal

`sync-native.js` implements the shipping profile in a headless browser/Node
module. It is based on the supplied `CurrentRootView.swift` CurrentSealPayload,
`CurrentReceiptModels.swift` RuntimeProofReceiptEvidenceItem, the VC exporter,
and p3's native reconstruction rules.

It verifies:

1. Full VC profile and explicit ES256/SHA-256/DER-signature metadata.
2. Intent SHA-256 in both disclosed encodings.
3. The exported evidence-manifest hash.
4. The allowlisted native evidence shape, with strict field types, unique IDs,
   and the original signed hash strings. Export-only descriptive fields are
   not mistaken for signed native evidence fields.
5. The original CurrentSealPayload: schema, intent, intentSha256, native
   evidence list, fixed native policyContext, and original createdAt.
6. Exactly one reconstructed payload digest in p3's bounded adjacent-time
   search: 300 seconds before to 5 seconds after each supported adjacent
   timestamp. Only exact digest equality identifies a candidate; those
   adjacent metadata times are not trusted timestamp attestations.
7. The native ES256 signature over the recovered canonical UTF-8 payload,
   using strict DER-to-P1363 conversion and Web Crypto's P-256 verification.
8. One exact accepted signing key/issuer/key-ID pin. The relying-party context
   must contain at most one public key for each `(issuer, key_id)` tuple, and a
   public key may not be duplicated under multiple pins. Ambiguous identities are
   refused before native verification. A valid signature with an unaccepted or
   ambiguously pinned key remains insufficient for a binding match.

Only the reconstructed integrity-protected payload supplies review intent and
evidence to the join. Unsigned aliases, declared digests, `signed_payload`
sidecars, receipt identifiers and display metadata are never substitutes.

The included real, previously bundled SYNC production receipt also passes this
native verification path and remains unaccepted without a supplied signer pin.
It does not contain the new review packet, so it is not a positive exact-action
fixture.

## 4. Gate and action agreement

The frozen p3 Gate v3 module remains unchanged in p3. The rc2 candidate copy
intentionally tightens one material-schema rule discovered in independent rc1
review: `payment.release.1.currency` must be an exact member of the packaged
closed ISO 4217 alpha-3 pin rather than merely a string. Apart from that
candidate correction, the wrapper requires the existing signature, signer-policy, material-schema,
attachment, consumption, lineage, outcome-axis and precision-preserving
lifecycle checks to pass.

It then requires:

- The Gate receipt-reference digest equals SHA-256 of the exact supplied
  SYNC VC bytes — no reserialization before this check.
- CAID is recomputed from the packet's typed action object and agrees with its
  hex action digest, the Gate CAID, the Gate action digest and the canonical
  Gate action object.
- The sealed tenant, operation and authority reference agree with Gate;
  tenant and authority also agree with the separately supplied policy context.
- The signed attachment time is no later than the recovered signed seal time;
  the seal time is no later than Gate's recorded admission time. The native
  payload has second-resolution dates; this does not invent higher-resolution
  device ceremony timing. Gate fractional timestamp semantics stay unchanged.
- Gate records `ADMITTED` and coherent `CONSUMED` state for that crossing.

Any missing leg, bad signature, substituted action, swapped reference,
unsupported profile, unaccepted signer or contradictory field yields
`REFUSED`, not a partial green result. Legacy v3 input without this wrapper
continues to display `NOT ASSESSED` for the extra human/action axis.

## 5. Replay — precisely scoped

A signed review packet is bound to an operation and tenant. Reusing it with a
new operation, tenant or authority reference fails even after a new valid Gate
signature is applied. A valid `ALREADY_CONSUMED` duplicate-refusal projection
cannot be represented as a freshly admitted human/action crossing.

`OPENVERIFIER-EXACT-ACTION-BATCH-v1` accepts an array of review bundles and
refuses all colliding positive entries when the same native seal or operation
would otherwise be counted twice. The native seal identity is derived from
**the actual signing-key fingerprint and protected native payload digest**.
Unsigned receipt IDs, alternate VC serialization, ECDSA randomness or
signature malleability do not create fresh authority. Both orderings of a
replay pair have the same refusal outcome.

This is not a live or globally complete replay database. An offline verifier
cannot discover an undisclosed admission on another server. Rechecking one
historical record is intentionally deterministic and does not spend anything.
Gate's durable, atomic consumption store remains responsible for preventing
replay at execution. Batch absence proves no global uniqueness.

## 6. Trust context

Context JSON has exactly these fields:

```json
{
  "profile": "OPENVERIFIER-ACTION-RELIANCE-v1",
  "tenant_id": "customer-tenant",
  "principal_authority_ref": "authority-reference",
  "accepted_gate_signers": [
    {"kid": "gate-key-id", "public_jwk": {"kty":"EC","crv":"P-256","x":"<base64url>","y":"<base64url>"}}
  ],
  "accepted_sync_signers": [
    {"issuer":"<SYNC issuer>","key_id":"<SYNC key ID>","public_key_b64":"<base64 raw P-256 point>"}
  ]
}
```

The `accepted_sync_signers` lane is a closed identity map: two entries with the
same `(issuer, key_id)` are invalid even when their public keys differ; duplicate
public-key bytes are also invalid. This prevents an otherwise valid receipt from
being accepted under an ambiguous human-signer identity.

Obtain and approve pins independently. Merely copying a key out of the presented
artifact does not establish authority. The browser loads this context through
a separate file control, keeps it in memory, and requires re-verification on
change. Context provenance is not attested by OpenVerifier. This mode neither
inherits p3's fixture keys nor silently trusts browser-local signer enrollment.

## 7. Envelope and outputs

A review bundle has exactly:

```text
profile = OPENVERIFIER-EXACT-ACTION-BINDING-v1
gate_projection = unchanged signed Gate v3 document, including exact receipt bytes
reviewed_action = { filename, media_type, bytes_b64url }
```

A batch has exactly `profile = OPENVERIFIER-EXACT-ACTION-BATCH-v1` and `bindings`.

Top-level positive output: `decision: VERIFIED`,
`human_machine_action_binding: MATCH`,
`claim_boundary.sync_receipt_action_binding_verified: true`.
Failure output: `decision: REFUSED` with a named reason and individual checks.
The nested legacy Gate result is preserved, including its own older limited
claim boundary; the new combined result owns the additional assessment.

Every result remains nonauthorizing and explicitly withholds display
attestation, human comprehension, civil identity, chain continuity, trusted
wall-clock time, live global replay state, canonical Gate provenance, provider
truth and physical outcome. An action-binding match can coexist with an
`INDETERMINATE` provider/effect outcome.

## 8. Parser and input limits

Strict UTF-8 and JSON parsing precede verification. Duplicate names (including
escaped aliases), lone surrogate code points, invalid base64url pad bits,
noncanonical packet encodings, unknown envelope keys and malformed DER
signatures are refused. Inputs are copied/parsed before asynchronous work.
Limits: 8 MiB bundle, 2 MiB native receipt, 1 MiB review packet, 256 KiB context,
48 JSON nesting levels, 128 native evidence entries, 64 keys per trust lane,
and 32 bundles per batch. The existing pinned action profile accepts only
safe integer JSON numbers; amounts are strings.
