D30-F05-A07 / Released engineering topic

Verify the Retained Object Version Without Inventing External Assurance

Hash the exact signed checkpoint envelope, inspect fixed retention and preserve uncertainty when the evidence is only a local model.

Verify the Retained Object Version Without Inventing External AssuranceD30 / D30-F05

A ledger team has signed a checkpoint and saved a receipt saying it is retained until 2033. That receipt lives beside the ledger. If the same operator can replace both files, the receipt has not supplied an independent point of comparison.

The useful question is precise: which exact object version holds which exact bytes, under which retention policy, as observed by whom and when? This tutorial implements a local inspection model for that question. Its canonical model passes all policy checks. Its live external assurance remains indeterminate.

A local model and independent assurance answer separate questions

Start with the bytes being retained

The shared Cedar example contains three whole committed groups and four journals. Its checkpoint signs a full-prefix chain head and Merkle root. Those details have already been validated by the preceding integrity topics; the Anchor input does not re-run the full ledger replay.

The signed envelope contains schema_version, key_id, algorithm, checkpoint and signature_hex. Its binary frame E includes every one of those fields. It is 524 bytes long, and its SHA256 is:

Plain text
8c3d6bb3a098a957a5b555064cda453528aff09995a63a944fd902076f523972

The checkpoint payload C alone is 300 bytes. Hashing C would omit the envelope's key label, algorithm and signature. Hashing pretty JSON would commit a different byte representation. A provider ETag is also not this SHA256 input. The body returned for the exact retained version must be hashed as bytes.

The frame uses explicit ASCII domain tags, one zero octet and unsigned four-octet big-endian UTF-8 lengths. Frozen field order defines the bytes. JSON object delivery order does not. Unknown fields reject so that an unsigned, silently ignored trust claim cannot be attached to the payload.

The independent fixture contains literal bytes as well as the expected digest. Both Python and TypeScript compare against those bytes; merely asserting that two implementations agree would be weaker evidence if they shared a framing mistake.

Address a version, then inspect its retention

The synthetic target is owner 123456789012, region us-east-1, bucket cedar-integrity-model, key checkpoints/2026/10/CHECKPOINT-4.bin and version model-version-001. Every part is compared exactly. The key and version preserve Unicode scalar values without trimming or normalization. Two visually similar NFC/NFD keys remain different identities.

S3 protection applies to an object version. New versions or a delete marker can coexist with an earlier protected version; checking only the latest key can therefore answer a different question. Fixed retention, variable retention and legal hold also have distinct semantics. Our selected COMPLIANCE profile requires an explicit fixed deadline. GOVERNANCE and legal-hold-only examples fail that selected policy; variable retention is unsupported and remains indeterminate. These are policy decisions, not a claim that the other features provide no protection. AWS Object Lock

The current retention API accepts versionId and expected bucket owner and includes event-hold fields. This package deliberately models the fixed-retention branch. A future adapter must preserve the provider's actual version and response rather than interpreting an unsupported event-held object as fixed retention. GetObjectRetention

HEAD retrieves metadata without the body, and permission differences can change absence errors. An unavailable or ambiguous 403 is uncertainty. It must not become a confident assertion that the version is absent or retention is disabled. Model not-found/delete-marker cases here are synthetic availability failures only. HeadObject

Work through the canonical receipt

The signer claims checkpoint creation at 24 October 2026, 12:00:00.000 UTC. The independently retained synthetic expected digest is available ten seconds later. The model object read is observed at 12:00:30.000. We evaluate at 12:01:00.000.

The candidate E digest and the fetched version body digest both match the retained expectation. The exact owner/region/bucket/key/version matches. The observation is 30 seconds old. Fixed COMPLIANCE retention lasts until 24 October 2033, 12:00:00.000, exactly the supplied minimum deadline. All eleven diagnostics pass.

The output is intentionally layered:

JSON
{
  "status": "indeterminate",
  "code": "MODEL_CONSISTENT_LIVE_ASSURANCE_INDETERMINATE",
  "model": {"status": "pass", "code": "MODEL_POLICY_CONSISTENT"},
  "external_assurance": {
    "status": "indeterminate",
    "code": "MODEL_RECEIPT_NOT_INDEPENDENT_PROVIDER_EVIDENCE"
  },
  "signature_assurance": {
    "status": "indeterminate",
    "code": "ANCHOR_DOES_NOT_VERIFY_SIGNATURE_TRUST"
  }
}

This excerpt omits the full diagnostic list for readability; the complete result retains every check and digest. A structurally valid Ed25519 signature string is not signature verification. One fixture even supplies self-consistent bytes and expectation containing an all-zero signature: the Anchor model can establish byte correspondence while signature assurance remains indeterminate. Use the signed-checkpoint topic for actual verification and independently configured key trust.

Test the exact boundaries

Minimum deadline equality and expiry equality have different outcomes

There are two different comparisons. The retention deadline must be at least the policy minimum; equality satisfies that requirement. Protection must still be active at as_of; equality with the actual expiry fails. A deadline one millisecond short fails the minimum. A later deadline satisfies it.

Observation freshness is another selected bound. Exactly 300 seconds is accepted. At 300.001 seconds the receipt becomes stale, so the model is indeterminate even when the previously observed bytes still match. The model does not claim to reconstruct provider state that it never observed.

A future model receipt is also indeterminate. Its content and retention payloads do not appear as derived selected evidence before their observation time. The whole strict shape is validated, so malformed future data cannot bypass validation. A read observed before the checkpoint's claimed creation fails internal chronology; neither timestamp proves the physical moment of signing.

Known failure wins over missing evidence. If the independent expected digest is missing but the supplied model clearly says GOVERNANCE, the selected COMPLIANCE policy fails. If all known facts are consistent but retention cannot be read, the result is indeterminate. Those outcomes tell the operator whether to investigate a contradiction or obtain missing evidence.

Run the same kernel in both languages

Python calls verify_external_anchor(request, envelope, receipt, context). TypeScript calls await verifyExternalAnchor(...); it uses standard WebCrypto SHA256 so the browser lab runs the canonical kernel. The Python implementation uses hashlib. There is no custom hash primitive, remote request or credential.

Python
from anchor import verify_external_anchor
result = verify_external_anchor(request, envelope, receipt, context)
assert result["external_assurance"]["status"] == "indeterminate"

Inputs are exact schemas. Numeric or Boolean counters, uppercase digest text, lone surrogates, invalid Gregorian clocks, a null version and extra fields reject. Body bytes are capped at 8192 octets; key/version bounds count UTF-8 octets. The algorithm uses O(B) time and memory for bounded bytes B. Outputs are detached from inputs.

Open the receipt inspection lab. Step through scope, expected commitment, exact version, observation, body and retention. Change the mode, version, deadline or body and inspect which check fails. Back reconstructs an earlier teaching view; it does not change an external object's retention. Reduced motion performs one step without a timer. The lab never creates an AWS object.

What an independent adapter would add

A production adapter would authenticate its configured endpoint/authority, request the exact version, read its bytes and retention under the expected owner, preserve responses and observation clocks, and bind them to an independently retained checkpoint expectation. It would also need permissions, account governance, encryption-key availability, monitoring and a policy for refresh or revocation. Retention alone does not make all of those dependencies disappear. Managing Object Lock

Blockchain would add another mechanism with chain identity, transaction inclusion, finality/reorganization and independent observation rules. It is a comparison here; no stub transaction receives a verified label. The completed local model is useful because it exposes precisely which additional evidence would be required.

The package contains 85 full expected-output cases and strict language parity, including the original 83 cases authored before core. Validation evidence records runtime and visual checks. Continue with Signed Ledger Checkpoint and End-to-End Ledger Integrity Verification to keep signature trust, source completeness and external assurance separately inspectable.

Model receipt verification

Caption: the model's arithmetic/metadata consistency and the authority of external evidence remain separate. An unavailable or future receipt never becomes a provider-verified success.

ReferencesPrimary sources and evidence notes

Expand the source trail, evidence role, and limitations behind the engineering choices.

All examples are synthetic. Historical reuse was not useful without a complete reusable provider receipt, expected checkpoint, independent authority and observation chronology. No historical external anchor is invented.

  1. AWS S3 Object Lock. Accessed: 2026-10-25. Supports: version-specific protection, fixed and variable retention, legal hold, COMPLIANCE/GOVERNANCE distinctions and coexistence of later versions/delete markers. Limitations: product semantics do not authenticate a local receipt, prescribe Cedar policy or establish legal sufficiency.
  2. GetObjectRetention API. Accessed: 2026-10-25. Supports: explicit versionId, expected-owner handling and current event-hold response fields. Limitations: this topic provides a normalized model, not a live API request or exhaustive provider adapter.
  3. HeadObject API. Accessed: 2026-10-25. Supports: metadata without body, explicit delete-marker behavior and permission-dependent absence errors. Limitations: HEAD/ETag alone does not verify the selected envelope bytes.
  4. Managing Object Lock. Accessed: 2026-10-25. Supports: retrieval permissions, governance bypass controls and encryption/key-management boundaries. Limitations: retention is not a blanket guarantee of recoverability or account survival.
  5. RFC8032. Accessed: 2026-10-25. Supports: pure Ed25519 context and public test-vector provenance used by the shared signed-checkpoint fixture. Limitations: this Anchor kernel does not validate signatures or a trust registry.
  6. W3C Web Cryptography Recommendation, 26 January 2017. Accessed: 2026-10-25. Supports: standard SHA-256 interface and secure-context requirement for the browser implementation. Limitations: API availability does not establish trusted provider evidence.
  7. Python hashlib. Accessed: 2026-10-25. Supports: standard SHA256 implementation used by Python. Limitations: a matching hash does not authenticate an independently retained expectation.

Authored material: strict JSON schemas, framing tags/field order, 8192-byte body bound, 300-second freshness, COMPLIANCE-only selected profile, minimum deadline and all Cedar synthetic receipts. The shared framing is not RFC8785 canonical JSON and does not claim Certificate Transparency protocol conformance.

anchor.ts
/** Pure version-specific retention model. Standard WebCrypto; no provider I/O. */
type O = Record<string, any>;
const keys = (s: string) => s.split(' ');
const REQUEST=keys('schema_version stream_id ledger_id entity_id checkpoint_id as_of policy');
const POLICY=keys('policy_id profile object min_retain_until');
const OBJECT=keys('expected_owner region bucket key version_id');
const ENVELOPE=keys('schema_version key_id algorithm checkpoint signature_hex');
const FIELDS=keys('schema_version checkpoint_id stream_id ledger_id entity_id created_at through_sequence group_count chain_head merkle_root merkle_size');
const RECEIPT=keys('schema_version receipt_id evidence_kind provider object observed_at content retention');
const CONTENT=keys('status bytes_hex response_ref');
const RETENTION=keys('status retention_type mode retain_until legal_hold response_ref');
const COMMITMENT=keys('stream_id ledger_id entity_id checkpoint_id envelope_sha256 available_at receipt_ref');
const SCOPE=keys('stream_id ledger_id entity_id checkpoint_id');
const EXTERNAL={status:'indeterminate',code:'MODEL_RECEIPT_NOT_INDEPENDENT_PROVIDER_EVIDENCE'};
const SIGNATURE={status:'indeterminate',code:'ANCHOR_DOES_NOT_VERIFY_SIGNATURE_TRUST'};
class Invalid extends Error {}
class CryptoUnavailable extends Error {}
function need(ok: unknown, code: string): asserts ok { if(!ok)throw new Invalid(code); }
function exact(value: unknown, fields: string[]): asserts value is O {
  need(value!==null && typeof value==='object' && !Array.isArray(value) && Object.keys(value).length===fields.length && fields.every(k=>Object.hasOwn(value,k)),'INVALID_SCHEMA');
}
function identifier(value: unknown): asserts value is string {need(typeof value==='string'&&/^[A-Za-z0-9][A-Za-z0-9._:-]{0,63}$/.test(value),'INVALID_IDENTIFIER');}
function stamp(value: unknown): number {
  need(typeof value==='string'&&/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}\.[0-9]{3}Z$/.test(value),'INVALID_TIMESTAMP');
  const parsed=new Date(value);need(!Number.isNaN(parsed.valueOf())&&parsed.toISOString()===value&&value.slice(0,4)!=='0000','INVALID_TIMESTAMP');return parsed.valueOf();
}
function hextext(value: unknown, size: number): value is string{return typeof value==='string'&&value.length===size&&/^[0-9a-f]+$/.test(value);}
function count(value: unknown, maximum: number): number {
  need(typeof value==='string'&&value.length<=4&&/^(0|[1-9][0-9]*)$/.test(value),'INVALID_CHECKPOINT');const n=Number(value);need(n<=maximum,'INVALID_CHECKPOINT');return n;
}
function opaque(value: unknown): value is string {
  if(typeof value!=='string')return false;
  for(const c of value){const n=c.codePointAt(0)!;if(n>=0xd800&&n<=0xdfff)return false;}
  const n=new TextEncoder().encode(value).length;return n>=1&&n<=1024;
}
function objectShape(value: unknown): asserts value is O {
  exact(value,OBJECT);
  need(typeof value.expected_owner==='string'&&/^[0-9]{12}$/.test(value.expected_owner),'INVALID_OBJECT_IDENTITY');
  need(typeof value.region==='string'&&value.region.length>=1&&value.region.length<=64&&/^[a-z0-9](?:[a-z0-9-]*[a-z0-9])?$/.test(value.region),'INVALID_OBJECT_IDENTITY');
  need(typeof value.bucket==='string'&&value.bucket.length>=3&&value.bucket.length<=63&&/^[a-z0-9][a-z0-9.-]*[a-z0-9]$/.test(value.bucket),'INVALID_OBJECT_IDENTITY');
  need(opaque(value.key)&&opaque(value.version_id)&&value.version_id!=='null','INVALID_OBJECT_IDENTITY');
}
function join(...parts: Uint8Array[]): Uint8Array {const out=new Uint8Array(parts.reduce((n,p)=>n+p.length,0));let i=0;for(const p of parts){out.set(p,i);i+=p.length;}return out;}
function u(n: number): Uint8Array{const b=new Uint8Array(4);new DataView(b.buffer).setUint32(0,n,false);return b;}
function s(t: string): Uint8Array{const b=new TextEncoder().encode(t);return join(u(b.length),b);}
const ascii=(t: string)=>new TextEncoder().encode(t);
/** Structural encoding only; no Ed25519/trust verification. */
export function encodeEnvelope(value: unknown): Uint8Array {
  exact(value,ENVELOPE);need(value.schema_version==='d30-signed-checkpoint-v1','UNSUPPORTED_SCHEMA');identifier(value.key_id);
  need(value.algorithm==='Ed25519','UNSUPPORTED_ALGORITHM');need(hextext(value.signature_hex,128),'INVALID_ENVELOPE');
  const cp=value.checkpoint;exact(cp,FIELDS);need(cp.schema_version==='d30-integrity-checkpoint-v1','UNSUPPORTED_SCHEMA');
  for(const k of SCOPE)identifier(cp[k]);stamp(cp.created_at);
  const sequence=count(cp.through_sequence,8192),groups=count(cp.group_count,4096),size=count(cp.merkle_size,4096);
  need(groups===size&&((groups===0&&sequence===0)||(groups>0&&groups<=sequence&&sequence<=2*groups)),'INVALID_CHECKPOINT');
  need(hextext(cp.chain_head,64)&&hextext(cp.merkle_root,64),'INVALID_CHECKPOINT');
  const c=join(ascii('D30-INTEGRITY-CHECKPOINT-V1\0'),...FIELDS.map(k=>s(cp[k])));
  return join(ascii('D30-SIGNED-CHECKPOINT-V1\0'),s(value.schema_version),s(value.key_id),s(value.algorithm),u(c.length),c,s(value.signature_hex));
}
function validate(r: unknown,e: unknown,receipt: unknown,ctx: unknown): {encoded:Uint8Array;asof:number;observed:number} {
  exact(r,REQUEST);need(r.schema_version==='d30-external-anchor-v1','UNSUPPORTED_SCHEMA');for(const k of SCOPE)identifier(r[k]);
  const asof=stamp(r.as_of),p=r.policy;exact(p,POLICY);identifier(p.policy_id);need(p.profile==='s3-fixed-compliance-v1','UNSUPPORTED_PROFILE');objectShape(p.object);stamp(p.min_retain_until);
  const encoded=encodeEnvelope(e);const envelope=e as O,created=envelope.checkpoint.created_at;
  need(created<=r.as_of,'CHECKPOINT_NOT_YET_CREATED');need(p.min_retain_until>=created,'INVALID_POLICY');
  exact(receipt,RECEIPT);need(receipt.schema_version==='d30-model-anchor-receipt-v1','UNSUPPORTED_SCHEMA');identifier(receipt.receipt_id);
  need(receipt.evidence_kind==='model','UNSUPPORTED_EVIDENCE_KIND');need(receipt.provider==='aws-s3','UNSUPPORTED_PROVIDER');objectShape(receipt.object);const observed=stamp(receipt.observed_at);
  const c=receipt.content;exact(c,CONTENT);identifier(c.response_ref);need(typeof c.status==='string'&&['read','unavailable','not-found','delete-marker'].includes(c.status),'INVALID_CONTENT');
  if(c.status==='read')need(typeof c.bytes_hex==='string'&&c.bytes_hex.length<=16384&&c.bytes_hex.length%2===0&&/^[0-9a-f]*$/.test(c.bytes_hex),'INVALID_CONTENT');
  else need(c.bytes_hex===null,'INVALID_CONTENT');
  const retention=receipt.retention;exact(retention,RETENTION);identifier(retention.response_ref);need(['read','unavailable'].includes(retention.status),'INVALID_RETENTION');
  if(retention.status==='unavailable')need(['retention_type','mode','retain_until','legal_hold'].every(k=>retention[k]===null),'INVALID_RETENTION');
  else {
    need(['fixed','variable','none'].includes(retention.retention_type),'INVALID_RETENTION');
    need(retention.mode===null||['COMPLIANCE','GOVERNANCE'].includes(retention.mode),'INVALID_RETENTION');
    need(retention.legal_hold===null||['ON','OFF'].includes(retention.legal_hold),'INVALID_RETENTION');if(retention.retain_until!==null)stamp(retention.retain_until);
    const kind=retention.retention_type;
    need((kind==='fixed'&&retention.mode!==null&&retention.retain_until!==null)||(kind==='variable'&&retention.mode!==null)||(kind==='none'&&retention.mode===null&&retention.retain_until===null),'INVALID_RETENTION');
  }
  exact(ctx,['expected_commitment']);const expected=ctx.expected_commitment;
  if(expected!==null){exact(expected,COMMITMENT);for(const k of SCOPE)identifier(expected[k]);identifier(expected.receipt_ref);need(hextext(expected.envelope_sha256,64),'INVALID_COMMITMENT');stamp(expected.available_at);need(expected.available_at>=created,'COMMITMENT_CLOCK_VIOLATION');}
  return{encoded,asof,observed};
}
async function sha(bytes:Uint8Array):Promise<string>{
  if(!globalThis.crypto?.subtle || typeof globalThis.crypto.subtle.digest!=='function')throw new CryptoUnavailable();
  try{const hash=await globalThis.crypto.subtle.digest('SHA-256',new Uint8Array(bytes));return Array.from(new Uint8Array(hash),n=>n.toString(16).padStart(2,'0')).join('');}
  catch(error){if(error instanceof DOMException&&['NotSupportedError','OperationError','SecurityError'].includes(error.name))throw new CryptoUnavailable();throw error;}
}
function fromHex(value:string):Uint8Array{return Uint8Array.from(value.match(/../g)??[],b=>parseInt(b,16));}
export async function verifyExternalAnchor(request:unknown,envelope:unknown,receipt:unknown,context:unknown):Promise<O> {
  try {
    const {encoded,asof,observed}=validate(request,envelope,receipt,context);
    const r=request as O,e=envelope as O,rec=receipt as O,ctx=context as O;
    const checks:O[]=[];const check=(name:string,status:string,code:string)=>{checks.push({check:name,status,code});};
    const gate=(name:string,ok:boolean,yes:string,no:string)=>check(name,ok?'pass':'fail',ok?yes:no);
    const expected=ctx.expected_commitment,p=r.policy,c=rec.content,retention=rec.retention,digest=await sha(encoded);
    gate('scope',SCOPE.every(k=>e.checkpoint[k]===r[k])&&(expected===null||SCOPE.every(k=>expected[k]===r[k])),'SCOPE_MATCH','SCOPE_MISMATCH');
    const knownExpected=expected!==null&&expected.available_at<=r.as_of;
    check('expected_commitment',knownExpected?'pass':'indeterminate',knownExpected?'EXPECTED_COMMITMENT_AVAILABLE':expected===null?'MISSING_EXPECTED_COMMITMENT':'EXPECTED_COMMITMENT_NOT_AVAILABLE');
    if(knownExpected)gate('envelope_commitment',digest===expected.envelope_sha256,'ENVELOPE_COMMITMENT_MATCH','EXPECTED_ENVELOPE_DIGEST_MISMATCH');else check('envelope_commitment','indeterminate','EXPECTED_COMMITMENT_NOT_AVAILABLE');
    gate('object_identity',OBJECT.every(k=>rec.object[k]===p.object[k]),'OBJECT_VERSION_IDENTITY_MATCH','OBJECT_VERSION_IDENTITY_MISMATCH');
    const future=rec.observed_at>r.as_of;
    if(c.status==='read'&&rec.observed_at<e.checkpoint.created_at)check('observation','fail','OBSERVATION_BEFORE_CHECKPOINT');
    else if(future)check('observation','indeterminate','RECEIPT_NOT_YET_AVAILABLE');else if(asof-observed>300000)check('observation','indeterminate','RECEIPT_STALE');else check('observation','pass','OBSERVATION_CURRENT');
    let bodyDigest:string|null=null;
    if(future)check('content_availability','indeterminate','RECEIPT_NOT_YET_AVAILABLE');
    else {const statuses:Record<string,[string,string]>={read:['pass','OBJECT_VERSION_READ'],unavailable:['indeterminate','OBJECT_UNAVAILABLE'],'not-found':['fail','OBJECT_VERSION_NOT_FOUND'],'delete-marker':['fail','OBJECT_VERSION_DELETE_MARKER']};check('content_availability',...statuses[c.status]);}
    if(!future&&c.status==='read'){bodyDigest=await sha(fromHex(c.bytes_hex));gate('content_digest',bodyDigest===digest,'OBJECT_CONTENT_MATCH','OBJECT_CONTENT_DIGEST_MISMATCH');}else check('content_digest','indeterminate','CONTENT_NOT_AVAILABLE');
    const fixed=!future&&retention.status==='read'&&retention.retention_type==='fixed';
    if(future)check('retention_type','indeterminate','RECEIPT_NOT_YET_AVAILABLE');else if(retention.status==='unavailable')check('retention_type','indeterminate','RETENTION_UNAVAILABLE');else if(retention.retention_type==='variable')check('retention_type','indeterminate','VARIABLE_RETENTION_UNSUPPORTED');else if(fixed)check('retention_type','pass','FIXED_RETENTION_SELECTED');else check('retention_type','fail','FIXED_RETENTION_REQUIRED');
    if(fixed){gate('retention_mode',retention.mode==='COMPLIANCE','COMPLIANCE_SELECTED','COMPLIANCE_REQUIRED');gate('minimum_retention',retention.retain_until>=p.min_retain_until,'MINIMUM_RETENTION_MET','RETENTION_TOO_SHORT');gate('active_retention',r.as_of<retention.retain_until,'RETENTION_ACTIVE','RETENTION_EXPIRED');}
    else for(const name of ['retention_mode','minimum_retention','active_retention'])check(name,'indeterminate','FIXED_RETENTION_NOT_ESTABLISHED');
    const failed=checks.find(c=>c.status==='fail'),unknown=checks.find(c=>c.status==='indeterminate');
    const model={status:failed?'fail':unknown?'indeterminate':'pass',code:(failed??unknown??{code:'MODEL_POLICY_CONSISTENT'}).code};
    const scope=Object.fromEntries(SCOPE.map(k=>[k,r[k]]));Object.assign(scope,{as_of:r.as_of,policy_id:p.policy_id});
    return{status:failed?'fail':'indeterminate',code:failed?failed.code:unknown?unknown.code:'MODEL_CONSISTENT_LIVE_ASSURANCE_INDETERMINATE',scope,envelope:{byte_length:String(encoded.length),envelope_sha256:digest,expected_sha256:knownExpected?expected.envelope_sha256:null,content_sha256:bodyDigest},model,external_assurance:{...EXTERNAL},signature_assurance:{...SIGNATURE},checks};
  }catch(error){if(error instanceof CryptoUnavailable)return{status:'indeterminate',code:'CRYPTO_UNAVAILABLE',scope:null,envelope:null,model:null,external_assurance:{...EXTERNAL},signature_assurance:{...SIGNATURE},checks:[]};if(!(error instanceof Invalid))throw error;return{status:'rejected',code:error.message,scope:null,envelope:null,model:null,external_assurance:{...EXTERNAL},signature_assurance:{...SIGNATURE},checks:[]};}
}
Full-height labanchor labOpen full screen
Written by

Fintech engineer building market-data and financial systems, and the author of every article, glossary record, and reference implementation on The Fintech Builder.