# Verification Semantics

URL: https://docs.nexart.io/docs/verification-semantics

Precise semantics of NexArt verification results, covering each status, the checks behind it, skipped checks for unattested records, and how to interpret.

This page resolves the ambiguities builders most often hit when integrating NexArt verification. Read it once before shipping.

## certificateHash Is the Source of Truth

`certificateHash` is the canonical identity of any Certified Execution Record. Always store and resolve artifacts by `certificateHash`.

- Public verification URL: `https://verify.nexart.io/c/{certificateHash}`
- SDK lookup, deduplication, audit trails: keyed on `certificateHash`
- For Project Bundles: `projectHash` plays the same role at the bundle level

##### executionId is not a unique artifact identifier

`executionId` is a convenience identifier returned by the certify API. It MUST NOT be used as the primary key for storage, deduplication, or public verification URLs. Use `certificateHash`.

## Resealed Artifacts Have a New Hash

The public verifier MAY return a redacted reseal instead of the original CER. A reseal exists so that artifacts containing sensitive metadata can still be publicly verified after redaction.

A reseal is a new bundle:

- bundleType: `signed-redacted-reseal`
- NEW certificateHash: covers the resealed (redacted) content
- Provenance pointer: references the ORIGINAL `certificateHash` (reference only, not validated)
- Fresh node signature: covers the resealed content

Reseal provenance shape (illustrative)

```
{
  "bundleType": "signed-redacted-reseal",
  "certificateHash": "sha256:<NEW resealed hash>",
  "provenance": {
    "originalCertificateHash": "sha256:<ORIGINAL hash>",
    "reason": "public-redaction",
    "resealedAt": "2026-04-19T10:12:00.000Z"
  },
  "snapshot": { "...redacted snapshot...": true },
  "meta": {
    "attestation": {
      "receipt": { "certificateHash": "sha256:<NEW resealed hash>" },
      "signature": "...",
      "kid": "key_..."
    }
  }
}
```

Rules to apply when you receive a reseal:

- The resealed `certificateHash` is what the verifier validates.
- The original `certificateHash` is reference-only in public context. Do not validate against it.
- Both hashes can legitimately coexist. They describe the same execution at different visibility levels.
- If your application stores the original hash, also store the resealed hash returned by the verifier; treat them as a pair.

## Context Signals: Inside vs Outside Hash Scope

Context signals MAY be transported either inside or outside the `certificateHash` scope:

- Inside the hash. Signals are part of the canonical bundle. Any change invalidates the hash. This is the strongest binding.
- Outside the hash. Signals are transported as supplemental metadata. They are recorded and visible, but their absence or modification does NOT invalidate `certificateHash`.

The verification report distinguishes the two. Signals outside the hash scope are reported as supplemental, not as a failure. Do not treat &quot;signals outside hash scope&quot; as a verification failure.

## Verification Result Classes

| Status | Meaning | Action |
| --- | --- | --- |
| VERIFIED | All applicable checks PASS. No supplemental notes. | Trust the artifact. |
| VERIFIED (supplemental) | Core integrity PASS. Supplemental context present but outside hash scope (e.g. unbound signals). | Trust the artifact. Note that supplemental fields are not cryptographically bound. |
| FAILED | One or more applicable checks FAIL. | Do not trust. Inspect the per-pillar report. |
| NOT_FOUND | Artifact not registered on the node. | Register on the node, then re-resolve. |

See Verification Reports for the full per-pillar semantics.

## Common Pitfalls

- Using `executionId` instead of `certificateHash` for lookup. The execution id is API convenience metadata; only certificateHash is the canonical identity.
- Sending `undefined` values inside metadata or signals. Some runtimes drop undefined keys before serialization, others coerce them. Either omit the key or use `null` to keep canonical JSON deterministic.
- Assuming all signals are hash-bound. They MAY be supplemental. Treat the verifier&#x27;s &quot;supplemental&quot; status as a normal result.
- Confusing the original `certificateHash` with the public resealed hash. Validate against whichever hash the verifier returns. Store both as a pair.
- Treating local `verifyProjectBundle()` as proof of public verifiability. It only proves integrity. See End-to-End Verification.

## Next

- End-to-End Verification: the full pipeline.
- How Verification Works: per-pillar checks.
- Attestation Node: reseal behavior at the node level.
