# Verify a Standing Mark without contacting the issuer

This workflow checks an existing signed record. It never pays, calls the issuer, creates a Mark, or authorizes an action.

## Install from the reviewed source

The package has not been newly published as part of this work. From a reviewed checkout:

```sh
cd sdk/typescript
npm install
npm run build
npm pack
```

Install that local package in your receiving application, or run the built command directly:

```sh
node sdk/typescript/dist/verify-cli.js record.json --policy receiver-policy.json
```

`record.json` may be the signed envelope itself or a retrieval response containing `envelope`. The command reads only local files. It does not retrieve a key or trust an embedded issuer claim.

## Admit an issuer before trusting one

The receiving party owns `receiver-policy.json`. Obtain and approve the issuer key through a channel your organization independently trusts. A key copied from the issuer's own record or website proves neither appointment nor authority.

Policy shape, with placeholders that must be replaced by your admitted values:

```json
{
  "public_key_base64": "RECEIVER_ADMITTED_ED25519_SPKI_BASE64",
  "trusted_key_ids": ["RECEIVER_ADMITTED_SHA256_OF_SPKI_DER"],
  "now": 1794343268
}
```

`now` is an optional caller-supplied Unix-second inspection time. Omit it to use the current clock. Do not copy the example time to claim current standing. An empty `trusted_key_ids` list deliberately leaves issuer recognition unestablished while still allowing mathematical signature inspection.

Keep receiver policy separately controlled from incoming records. Do not let the sender write the policy file or supply its admitted fingerprints.

## Read the result

- Exit 0: the existing verification contract returns `VALID` for that envelope and receiver policy.
- Exit 2: invalid, unrecognized, malformed, or otherwise unverifiable. Inspect the machine-readable JSON result.
- `signature_valid` answers the cryptographic question.
- `issuer_recognized` answers whether your policy admitted the signing key.
- `record_schema_valid`, `identifier_matches`, and hash checks answer structural questions.
- `decision_integrity.recorded_authoritative` reports the record's assertion. It is not an independent re-examination.
- `temporal_status` reports the recorded window, not a live revocation registry.
- `action_authorized` is always false. Your application must make its separate action decision.
- The command never treats unsupported current/revoked/superseded states as established.

For exact received-material, question, operation, and scope matching, use the SDK's existing `inspectEvidenceGate` with separately admitted trust and your own expected values. A valid envelope alone does not establish that it applies to the object your system is about to use.

For signed root-bundle distribution and historical key lifecycle checks, use the existing `inspectTrustBundle` and `inspectRecordWithTrust` APIs. Their root pin must still be independently admitted. This command does not create a new root or silently accept one.

## Python receiving systems

The existing Python CLI remains available:

```sh
PYTHONPATH=sdk/python python3 -m whp_standing_sdk input.json
```

It supports the existing record/key and signed trust-bundle input formats. Use a receiver-controlled input assembly; never accept sender-supplied trust policy as your own. The TypeScript command's separate `--policy` file makes that boundary explicit for shell-based receivers.

## Evidence

The CLI tests use locally generated test-only signatures on clearly identified fixture derivatives, not new service examinations. They cover a valid separately pinned record, an unadmitted issuer, missing receiver policy, tampered material, duplicate JSON keys, malformed policy, and a disabled fetch function. Existing TypeScript SDK tests also check trust-bundle rollback, key retirement/compromise, and cross-language agreement.
