Skip to main content
Jira progress: loading…

ZAR-AR

End-to-End Audit Replay Flow

1. Purpose

The Audit Replay Flow enables full deterministic reconstruction of any signal produced within ZAYAZ.

It allows auditors, regulators, and internal systems to:

  • trace a data point back to its origin
  • verify all transformations applied
  • reproduce the exact computation path
  • validate trust decisions

ZAYAZ does not just store results — it can replay how they were produced.


2. Core Principle

Every signal instance is reconstructable through three linked layers:

USO (What happened)
→ TrustGate (Was it valid?)
→ Execution Audit (How exactly did it happen?)

3. Replay Architecture


4. Replay Flow (Step-by-Step)

Step 1 — Identify Signal Instance

Start with a known uso_id:

identify-signal-instance.sqlGitHub ↗
SELECT *
FROM zar.uso_instance
WHERE uso_id = '0196F...';

This returns:

  • csi (signal type)
  • origin_chain (CMIs)
  • origin_chain_codes
  • trustgate_event_id

Step 2 — Resolve Producing Artifacts

resolve-producing-artifacts.sqlGitHub ↗
SELECT *
FROM zar.cmi_registry
WHERE cmi = ANY(origin_chain);

This provides:

  • exact artifact versions
  • git_sha
  • build_hash
  • execution references

Step 3 — Retrieve Validation Decisions

retrieve-validation-decisions.sqlGitHub ↗
SELECT *
FROM zar.trustgate_telemetry
WHERE trustgate_event_id = 'tg_evt_...';

Returns:

  • trust_score
  • policy_id
  • validator_id
  • decision (pass, fail, etc.)

Step 4 — Retrieve Execution Events

SELECT *
FROM zar.execution_audit_event
WHERE uso_id = '0196F...'
ORDER BY observed_at;

Returns:

  • input payloads
  • output payloads
  • transformation steps
  • replay context

Step 5 — Reconstruct Execution

Using:

  • origin_chain (CMIs)
  • execution_audit_event
  • git_sha

The system:

  • loads exact code versions
  • replays transformations in order
  • reproduces final output

Step 6 — Compare Results

CheckDescription
Output matchRecomputed output vs stored output
Hash validationInput/output integrity
Trust consistencySame TrustGate decision reproduced

5. Example Replay Scenario

Input

example-replay-scenario-input.jsonGitHub ↗
{
"uso_id": "0196F...",
"csi": "MICE.InvoiceEmissions.OUTPUT.CO2E.1_0",
"origin_chain_codes": ["MIE12","TG3K7"]
}

Replay Result

example-replay-scenario-result.jsonGitHub ↗
{
"replay_status": "success",
"output_match": true,
"trust_consistent": true,
"recomputed_trust_score": 0.9825,
"deviations": []
}

6. TrustGate Integration

TrustGate plays a critical role in replay:

  • validates the original execution
  • provides policy + validator context
  • allows recomputation of trust scores

Key Fields

FieldPurpose
trustgate_event_idLink between USO and validation
policy_idGoverning rule
validator_idValidation logic
trust_scoreConfidence metric

7. Execution Audit Layer

Execution audit events provide full replay fidelity.

Stored Information

CategoryDescription
InputRaw payload before processing
OutputResult after processing
TransformationOperation performed
EngineExecuting artifact (CMI)
ContextRuntime metadata

8. Guarantees

The replay system guarantees:

GuaranteeDescription
DeterminismSame input + same code → same output
TraceabilityFull lineage from origin to output
VerifiabilityIndependent replay possible
IntegrityHash validation across steps

9. Failure Modes

FailureMeaning
Output mismatchCode changed or data corrupted
Missing artifactZAR registry incomplete
Missing audit eventIncomplete logging
Trust mismatchValidation logic drift

10. Design Principles

  1. Separation of concerns
    • USO = identity + lineage
    • TrustGate = validation
    • Audit = execution detail
  2. Replay over storage
    • System prioritizes reproducibility over redundancy
  3. Deterministic architecture
    • No hidden transformations
  4. Audit-first design
    • Every signal is inherently auditable

11. Strategic Impact

This architecture enables:

  • CSRD-grade auditability
  • ISO-compliant traceability
  • Financial-grade data verification
  • Regulator-level transparency

ZAYAZ transforms ESG reporting from static disclosure into reproducible computation.


12. Extensions

  • Cryptographic signing of audit chains
  • Cross-system replay (multi-tenant verification)
  • Zero-knowledge proof validation
  • Regulator API access

Summary

The Audit Replay Flow ensures that:

  • every signal can be reconstructed
  • every decision can be explained
  • every output can be verified

If it cannot be replayed, it cannot be trusted.


APPENDIX A — Cryptographic Sealing Layer

Purpose

The Cryptographic Sealing Layer ensures that all provenance, validation, and execution records are tamper-evident and verifiable across time and systems.

It extends the Audit Replay Flow by adding cryptographic guarantees on top of:

  • USO lineage
  • TrustGate telemetry
  • Execution audit events

If data changes, the system will know.


A.1. Core Concept

Each step in the signal lifecycle contributes to a hash chain:

Each node:

  • hashes its payload
  • includes the previous hash
  • produces a new hash

A.2. Hash Chain Structure

Each execution or validation event includes:

FieldDescription
event_hashSHA-256 hash of current event payload
previous_hashHash of prior event in chain
chain_hashCombined hash (current + previous)

Example

hash-chain-structure.jsonGitHub ↗
{
"event_id": "evt_001",
"event_hash": "abc123...",
"previous_hash": "def456...",
"chain_hash": "xyz789..."
}

A.3. Final Seal

At publication or export, a final seal hash is generated:

seal_hash = SHA256(
uso_id +
concatenated_chain_hashes +
trustgate_event_id
)

This seal:

  • represents the entire lifecycle
  • is immutable
  • can be externally verified

A.4. Storage Strategy

LayerStorage
USOstores seal_hash (optional reference)
TrustGatereferences validation hash
execution_audit_eventstores chain-level hashes

A.5. Verification Process

To verify integrity:

  1. Recompute all event hashes
  2. Rebuild the chain
  3. Compare final seal hash

If mismatch:

→ tampering or corruption detected


A.6. Optional Extensions

ExtensionDescription
Digital signaturesSign seal with private key
Blockchain anchoringStore seal hash externally
Merkle treesBatch verification for large datasets
Zero-knowledge proofsVerify without exposing raw data

A.7. Design Principles

  • Append-only hash chaining
  • No mutable audit fields
  • Independent verification possible
  • Minimal performance overhead

A.8. Strategic Impact

This layer enables:

  • regulator-grade audit integrity
  • legal defensibility of ESG data
  • cross-system trust verification

ZAYAZ does not rely on trust — it proves integrity.


APPENDIX B — Auditor Interface (Replay & Explainability)

Purpose

The Auditor Interface provides a human-accessible layer for:

  • inspecting signal lineage
  • replaying computations
  • understanding trust decisions

It bridges:

  • technical provenance systems
  • auditor and regulator workflows

B.1. Core Interaction


B.2. Key Features

🔁 Replay Signal

  • Button: “Replay this signal”
  • Input: uso_id
  • Output:
    • reconstructed result
    • validation outcome
    • trust score comparison

🔍 Lineage Visualization

Displays:

  • origin chain (CMIs)
  • ZAR codes
  • transformation steps

Example:

MIE12 → DSA9Q → TG3K7


📊 Trust Explanation Panel

Shows:

FieldDescription
trust_scoreFinal score
policy_idGoverning policy
validator_idValidation logic
decisionpass / fail
reasoninghuman-readable explanation

🧾 Audit Timeline

Chronological view:

[09:40] Signal created (MIE12)
[09:41] Normalized (DSA9Q)
[09:42] Validated (TG3K7)

🔐 Integrity Status

Displays:

  • seal hash status
  • verification result
  • tamper detection

B.3. Example UI Layout

--------------------------------------------------
Signal Overview
--------------------------------------------------
CSI: MICE.InvoiceEmissions.OUTPUT.CO2E.1_0
USO ID: 0196F...
Trust Score: 0.9825 ✅
[ Replay Signal ]
--------------------------------------------------
Lineage
--------------------------------------------------
MIE12 → DSA9Q → TG3K7
--------------------------------------------------
Trust Explanation
--------------------------------------------------
Policy: TG-POLICY-SIGNAL-VALIDATION-v1
Validator: trustgate.signal.required_fields.v1
Decision: PASS
--------------------------------------------------
Audit Timeline
--------------------------------------------------
09:40 Created
09:41 Processed
09:42 Validated
--------------------------------------------------
Integrity
--------------------------------------------------
Seal Hash: VALID ✅

B.4. API Integration

The UI interacts with:

EndpointPurpose
/uso/{uso_id} retrieve instance
/trustgate/telemetry/{event_id}validation
/execution/replay/{uso_id}replay
/execution/audit/{uso_id}audit trail

B.5. Design Principles

  • Explainability over opacity
  • Human-readable + machine-verifiable
  • Minimal cognitive load
  • Full traceability in one interface

B.6. Target Users

  • External auditors
  • Internal compliance teams
  • Regulators
  • ESG analysts

B.7. Strategic Impact

This interface enables:

  • audit-ready ESG reporting
  • reduced audit costs
  • real-time verification
  • increased stakeholder trust

ZAYAZ does not just expose data — it explains it.


Appendix C — Cryptographic Sealing vs Hyperledger Fabric

Purpose

This appendix clarifies:

  • when to use the Cryptographic Sealing Layer
  • when to use Hyperledger Fabric
  • why combining both creates a regulator-grade trust architecture

These two mechanisms serve different but complementary roles in ZAYAZ.


C.1. Conceptual Distinction

ZAYAZ separates trust into two layers:

LayerFunctionScope
Cryptographic SealingInternal integrity and replay validationWithin ZAYAZ
Hyperledger FabricExternal trust and non-repudiationAcross organizations

C.2. Cryptographic Sealing Layer

Role

The Cryptographic Sealing Layer ensures that:

  • execution history is tamper-evident
  • audit trails are internally verifiable
  • signal outputs are deterministically reproducible

What it protects

  • USO lineage chains
  • execution audit events
  • TrustGate validation results

Guarantees

GuaranteeDescription
IntegrityData has not been altered
DeterminismSame inputs reproduce same outputs
ReplayabilityFull lifecycle can be reconstructed

When to use

Use always:

  • every signal instance
  • every audit trail
  • every validation flow

Cryptographic sealing is the default trust mechanism inside ZAYAZ.


C.3. Hyperledger Fabric

Role

Hyperledger Fabric provides:

  • external verification
  • multi-party consensus
  • non-repudiation of data existence

What it protects

  • final disclosures
  • high-value outputs
  • cross-organizational data exchanges

Guarantees

GuaranteeDescription
Non-repudiationData cannot be denied after anchoring
External trustIndependent parties can verify
Immutability (distributed)No single actor can rewrite history

C.4. When to Use Hyperledger Fabric

Hyperledger Fabric should be used selectively, not universally.

  • CSRD / ESRS disclosures
  • Carbon Passport (CPI) outputs
  • Regulatory submissions
  • Inter-company data exchanges
  • High-value ESG metrics
  • raw execution logs
  • intermediate transformation steps
  • TrustGate telemetry events

Fabric is a trust anchor, not a logging system.


C.5. Combined Architecture

ZAYAZ achieves maximum trust by stacking both layers:


APPENDIX D — Cryptographic Sealing vs Hyperledger Fabric

Purpose

This appendix clarifies:

  • when to use the Cryptographic Sealing Layer
  • when to use Hyperledger Fabric
  • why combining both creates a regulator-grade trust architecture These two mechanisms serve different but complementary roles in ZAYAZ.

D.1. Conceptual Distinction

ZAYAZ separates trust into two layers:

LayerFunctionScope
Cryptographic SealingInternal integrity and replay validationWithin ZAYAZ
Hyperledger FabricExternal trust and non-repudiationAcross organizations

D.2. Cryptographic Sealing Layer

Role

The Cryptographic Sealing Layer ensures that:

  • execution history is tamper-evident
  • audit trails are internally verifiable
  • signal outputs are deterministically reproducible

What it protects

  • USO lineage chains
  • execution audit events
  • TrustGate validation results

Guarantees

GuaranteeDescription
IntegrityData has not been altered
DeterminismSame inputs reproduce same outputs
ReplayabilityFull lifecycle can be reconstructed

When to use

Use always:

  • every signal instance
  • every audit trail
  • every validation flow

Cryptographic sealing is the default trust mechanism inside ZAYAZ.


D.3. Hyperledger Fabric

Role

Hyperledger Fabric provides:

  • external verification
  • multi-party consensus
  • non-repudiation of data existence

What it protects

  • final disclosures
  • high-value outputs
  • cross-organizational data exchanges

Guarantees

GuaranteeDescription
Non-repudiationData cannot be denied after anchoring
External trustIndependent parties can verify
Immutability (distributed)No single actor can rewrite history

D.4. When to Use Hyperledger Fabric

Hyperledger Fabric should be used selectively, not universally.

  • CSRD / ESRS disclosures
  • Carbon Passport (CPI) outputs
  • Regulatory submissions
  • Inter-company data exchanges
  • High-value ESG metrics
  • raw execution logs
  • intermediate transformation steps
  • TrustGate telemetry events

Fabric is a trust anchor, not a logging system.


D.5. Combined Architecture

ZAYAZ achieves maximum trust by stacking both layers:


D.6. Combined Flow

  1. Execution produces audit events
  2. Hash chain is built internally
  3. Final seal_hash is generated
  4. seal_hash is anchored to Hyperledger Fabric
  5. External parties verify against the anchor

D.7. Verification Model

Internal verification

  • recompute hash chain
  • validate seal hash
  • replay execution

External verification

  • retrieve anchored seal hash
  • compare with recomputed value

D.8. Why the Combination is Strong

CapabilityCryptographic SealingHyperledger FabricCombined
Tamper detection⚠️
Replay capability
External trust
Deterministic audit
Non-repudiation

D.9. Design Principle

Cryptographic Sealing proves that data is internally consistent.

Hyperledger Fabric proves that data has not been externally altered.


D.10. Strategic Impact

The combination enables:

  • regulator-grade ESG verification
  • cross-border audit trust
  • independent third-party validation
  • legally defensible disclosures

ZAYAZ does not rely on trust — it proves integrity internally and anchors trust externally.


D.11. Implementation Guidance

Always implement

  • hash chains in execution_audit_event
  • seal hash generation per signal lifecycle

Selectively implement

  • Fabric anchoring for:
    • final outputs
    • disclosures
    • CPI records

Summary

  • Cryptographic sealing = internal truth
  • Hyperledger Fabric = external trust
  • Together = complete trust architecture

If it cannot be verified internally, it cannot be trusted. If it cannot be anchored externally, it cannot be proven.


APPENDIX E - Hyperledger Fabric Anchor Layer

Purpose

The Hyperledger Fabric Anchor Layer provides external, multi-party verification for high-value ZAYAZ outputs.

It does not store full audit trails, raw ESG data, or execution payloads.

Instead, it anchors compact cryptographic proofs produced by the internal ZAYAZ Cryptographic Sealing Layer.

Execution Audit Events

Hash Chain

Seal Hash

Hyperledger Fabric Anchor

External Verification

This allows external parties to verify that a ZAYAZ output existed at a specific point in time and has not been altered since anchoring.


Note: See also the section ("Blockchain Verification Layer")[https://specs.zayaz.io/shared-intelligence/blockchain-verifier]


E.1. Design Principle

ZAYAZ stores the evidence. Fabric stores the proof that the evidence existed.

The Fabric ledger should contain only:

  • seal hashes
  • identifiers
  • timestamps
  • status metadata
  • optional external references

It should not contain:

  • raw ESG data
  • full audit logs
  • personal data
  • confidential client payloads
  • full execution snapshots

E.2. Relationship to Cryptographic Sealing

LayerResponsibility
Cryptographic SealingBuilds internal hash chain and generates seal_hash
Hyperledger FabricAnchors seal_hash externally
ZAYAZ Verification APIRecomputes seal and compares it with Fabric anchor

Fabric chaincode should therefore not recompute the entire audit trail.

It should enforce:

  • uniqueness
  • lifecycle state
  • submitter identity
  • anchor immutability
  • revocation / supersession rules

The Fabric ledger should store:

seal-anchor.jsonGitHub ↗
{
"anchor_id": "anc_0196F...",
"anchor_type": "uso_instance_seal",
"seal_hash": "sha256:...",
"hash_algorithm": "SHA-256",

"subject_type": "uso_id",
"subject_id": "0196F...",

"uso_id": "0196F...",
"signal_registry_id": 123,
"signal_id": "sssr:compute_method_registry.created_at",

"trustgate_telemetry_id": 1,
"trustgate_event_id": "tg_evt_...",

"execution_audit_event_id": "exec_evt_...",
"report_id": null,
"carbon_passport_id": null,

"zayaz_tenant_id": "tenant_viroway",
"framework_context": ["ESRS", "CSRD"],

"anchor_status": "active",
"created_at": "2026-04-28T09:07:16Z",
"created_by_org": "VirowayMSP",

"supersedes_anchor_id": null,
"metadata_hash": "sha256:..."
}

It should not store:

  • raw ESG values
  • customer names
  • supplier details
  • evidence files
  • payload snapshots
  • personal data
  • proprietary computation details

E.4. Chaincode State Model

Key

Use deterministic ledger keys.

anchor:{anchor_id}
seal_hash:{seal_hash}
subject:{subject_type}:{subject_id}

Recommended primary key:

anchor:{anchor_id}

Recommended secondary lookups:

seal_hash:{seal_hash} → anchor_id
subject:{subject_type}:{subject_id} → latest anchor_id

Fabric chaincode can use world state operations such as GetState() and PutState() to read and write ledger state; Fabric’s contract API exposes these through the transaction context/stub model. 


E.5. Chaincode Functions

E.5.1. CreateSealAnchor

Creates a new immutable anchor.

CreateSealAnchor(anchorJson)

Required fields:

  • anchor_id
  • seal_hash
  • seal_type
  • subject_id
  • subject_type
  • created_at

Validation rules:

  • anchor_id must not already exist
  • seal_hash must not already exist as active
  • seal_hash must match allowed hash format
  • submitter MSP must be allowed to anchor
  • anchor_status must start as active

E.5.2. GetSealAnchor

Reads an anchor by ID.

GetSealAnchor(anchor_id)

Returns:

get-seal-anchor-return.jsonGitHub ↗
{
"anchor_id": "...",
"seal_hash": "...",
"anchor_status": "active",
"created_at": "..."
}

This should be invoked as a read-only transaction from application clients. Fabric Gateway client APIs distinguish between evaluating transactions that query ledger state and submitting transactions that update ledger state. 


E.5.3. GetAnchorBySealHash

Looks up anchor by seal hash.

GetAnchorBySealHash(seal_hash)

Returns the matching anchor record if found.


E.5.4. GetLatestAnchorForSubject

Returns latest anchor for a subject.

GetLatestAnchorForSubject(subject_type, subject_id)

Example:

GetLatestAnchorForSubject("uso_id", "0196F...")


E.5.5. SupersedeSealAnchor

Creates a new anchor that supersedes an older one.

SupersedeSealAnchor(old_anchor_id, new_anchor_json, reason)

Rules:

  • old anchor remains immutable
  • old anchor status becomes superseded
  • new anchor references old anchor in supersedes_anchor_id
  • reason is stored in supersession_reason

This is used when a report or disclosure is corrected, not when the old anchor was “edited.”


E.5.6. RevokeSealAnchor

Marks an anchor as revoked.

RevokeSealAnchor(anchor_id, reason)

Rules:

  • only governance MSP or authorized admin MSP can revoke
  • anchor record is not deleted
  • status becomes revoked
  • revoked_at and revocation_reason are stored

Revocation is for invalid anchors, not normal corrections.


E.6. Chaincode Events

Emit chaincode events for external listeners.

Recommended events:

SealAnchorCreated
SealAnchorSuperseded
SealAnchorRevoked

Example event payload:

example-chaincode-event-payload.jsonGitHub ↗
{
"event_type": "SealAnchorCreated",
"anchor_id": "anc_0196F...",
"seal_hash": "sha256:...",
"subject_type": "uso_id",
"subject_id": "0196F...",
"created_at": "2026-04-28T09:07:16Z"
}

E.7. TypeScript Chaincode Skeleton

import { Context, Contract, Info, Returns, Transaction } from 'fabric-contract-api';
type AnchorStatus = 'active' | 'superseded' | 'revoked';
type SealAnchor = {
anchor_id: string;
seal_hash: string;
seal_type: string;
subject_id: string;
subject_type: string;
signal_id?: string | null;
trustgate_event_id?: string | null;
execution_audit_event_id?: string | null;
zayaz_tenant_id?: string | null;
framework_context?: string[];
anchor_status: AnchorStatus;
created_at: string;
created_by_org: string;
supersedes_anchor_id?: string | null;
supersession_reason?: string | null;
revoked_at?: string | null;
revocation_reason?: string | null;
metadata_hash?: string | null;
};
@Info({
title: 'ZayazSealAnchorContract',
description: 'Hyperledger Fabric chaincode for anchoring ZAYAZ cryptographic seal hashes.',
})
export class ZayazSealAnchorContract extends Contract {
private anchorKey(anchorId: string): string {
return `anchor:${anchorId}`;
}
private sealHashKey(sealHash: string): string {
return `seal_hash:${sealHash}`;
}
private subjectKey(subjectType: string, subjectId: string): string {
return `subject:${subjectType}:${subjectId}`;
}
private assertHashFormat(sealHash: string): void {
if (!/^sha256:[a-fA-F0-9]{64}$/.test(sealHash)) {
throw new Error(`Invalid seal_hash format: ${sealHash}`);
}
}
private getClientOrg(ctx: Context): string {
return ctx.clientIdentity.getMSPID();
}
private assertCanAnchor(ctx: Context): void {
const msp = this.getClientOrg(ctx);
const allowed = ['VirowayMSP', 'AuditorMSP', 'RegulatorMSP'];
if (!allowed.includes(msp)) {
throw new Error(`MSP not authorized to anchor: ${msp}`);
}
}
@Transaction()
public async CreateSealAnchor(ctx: Context, anchorJson: string): Promise<void> {
this.assertCanAnchor(ctx);
const anchor = JSON.parse(anchorJson) as SealAnchor;
if (!anchor.anchor_id) throw new Error('anchor_id is required');
if (!anchor.seal_hash) throw new Error('seal_hash is required');
if (!anchor.subject_id) throw new Error('subject_id is required');
if (!anchor.subject_type) throw new Error('subject_type is required');
this.assertHashFormat(anchor.seal_hash);
const anchorKey = this.anchorKey(anchor.anchor_id);
const existingAnchor = await ctx.stub.getState(anchorKey);
if (existingAnchor && existingAnchor.length > 0) {
throw new Error(`Anchor already exists: ${anchor.anchor_id}`);
}
const sealHashKey = this.sealHashKey(anchor.seal_hash);
const existingSeal = await ctx.stub.getState(sealHashKey);
if (existingSeal && existingSeal.length > 0) {
throw new Error(`Seal hash already anchored: ${anchor.seal_hash}`);
}
const clientOrg = this.getClientOrg(ctx);
const now = new Date().toISOString();
const normalized: SealAnchor = {
...anchor,
anchor_status: 'active',
created_at: anchor.created_at || now,
created_by_org: clientOrg,
supersedes_anchor_id: anchor.supersedes_anchor_id ?? null,
metadata_hash: anchor.metadata_hash ?? null,
};
await ctx.stub.putState(anchorKey, Buffer.from(JSON.stringify(normalized)));
await ctx.stub.putState(sealHashKey, Buffer.from(anchor.anchor_id));
await ctx.stub.putState(
this.subjectKey(anchor.subject_type, anchor.subject_id),
Buffer.from(anchor.anchor_id),
);
ctx.stub.setEvent(
'SealAnchorCreated',
Buffer.from(JSON.stringify({
event_type: 'SealAnchorCreated',
anchor_id: normalized.anchor_id,
seal_hash: normalized.seal_hash,
subject_type: normalized.subject_type,
subject_id: normalized.subject_id,
created_at: normalized.created_at,
})),
);
}
@Transaction(false)
@Returns('string')
public async GetSealAnchor(ctx: Context, anchorId: string): Promise<string> {
const data = await ctx.stub.getState(this.anchorKey(anchorId));
if (!data || data.length === 0) {
throw new Error(`Anchor not found: ${anchorId}`);
}
return data.toString();
}
@Transaction(false)
@Returns('string')
public async GetAnchorBySealHash(ctx: Context, sealHash: string): Promise<string> {
this.assertHashFormat(sealHash);
const anchorIdBytes = await ctx.stub.getState(this.sealHashKey(sealHash));
if (!anchorIdBytes || anchorIdBytes.length === 0) {
throw new Error(`No anchor found for seal hash: ${sealHash}`);
}
return this.GetSealAnchor(ctx, anchorIdBytes.toString());
}
@Transaction(false)
@Returns('string')
public async GetLatestAnchorForSubject(
ctx: Context,
subjectType: string,
subjectId: string,
): Promise<string> {
const anchorIdBytes = await ctx.stub.getState(this.subjectKey(subjectType, subjectId));
if (!anchorIdBytes || anchorIdBytes.length === 0) {
throw new Error(`No anchor found for subject: ${subjectType}:${subjectId}`);
}
return this.GetSealAnchor(ctx, anchorIdBytes.toString());
}
@Transaction()
public async SupersedeSealAnchor(
ctx: Context,
oldAnchorId: string,
newAnchorJson: string,
reason: string,
): Promise<void> {
this.assertCanAnchor(ctx);
const oldKey = this.anchorKey(oldAnchorId);
const oldBytes = await ctx.stub.getState(oldKey);
if (!oldBytes || oldBytes.length === 0) {
throw new Error(`Old anchor not found: ${oldAnchorId}`);
}
const oldAnchor = JSON.parse(oldBytes.toString()) as SealAnchor;
if (oldAnchor.anchor_status !== 'active') {
throw new Error(`Only active anchors can be superseded: ${oldAnchorId}`);
}
oldAnchor.anchor_status = 'superseded';
oldAnchor.supersession_reason = reason;
await ctx.stub.putState(oldKey, Buffer.from(JSON.stringify(oldAnchor)));
const newAnchor = JSON.parse(newAnchorJson) as SealAnchor;
newAnchor.supersedes_anchor_id = oldAnchorId;
await this.CreateSealAnchor(ctx, JSON.stringify(newAnchor));
ctx.stub.setEvent(
'SealAnchorSuperseded',
Buffer.from(JSON.stringify({
event_type: 'SealAnchorSuperseded',
old_anchor_id: oldAnchorId,
new_anchor_id: newAnchor.anchor_id,
reason,
})),
);
}
@Transaction()
public async RevokeSealAnchor(
ctx: Context,
anchorId: string,
reason: string,
): Promise<void> {
const msp = this.getClientOrg(ctx);
if (!['VirowayMSP', 'RegulatorMSP'].includes(msp)) {
throw new Error(`MSP not authorized to revoke: ${msp}`);
}
const key = this.anchorKey(anchorId);
const data = await ctx.stub.getState(key);
if (!data || data.length === 0) {
throw new Error(`Anchor not found: ${anchorId}`);
}
const anchor = JSON.parse(data.toString()) as SealAnchor;
anchor.anchor_status = 'revoked';
anchor.revoked_at = new Date().toISOString();
anchor.revocation_reason = reason;
await ctx.stub.putState(key, Buffer.from(JSON.stringify(anchor)));
ctx.stub.setEvent(
'SealAnchorRevoked',
Buffer.from(JSON.stringify({
event_type: 'SealAnchorRevoked',
anchor_id: anchorId,
reason,
revoked_at: anchor.revoked_at,
})),
);
}
}

E.8. Fabric Deployment Notes

Use Fabric v2.x lifecycle with organization approval before committing chaincode. Fabric v2.x introduced a decentralized chaincode lifecycle where multiple organizations agree on chaincode parameters before deployment. 

Recommended chaincode name:

zayaz-seal-anchor

Recommended channel:

zayaz-audit-anchor

Recommended organizations:

VirowayMSP
AuditorMSP
RegulatorMSP
PartnerMSP

E.9. Anchoring API

The ZAYAZ Admin API should wrap Fabric interactions. Application clients should not call Fabric directly.

E.9.1. POST /admin/fabric/anchors/create

Creates a Fabric anchor for a computed seal_hash.

Request

fabric-anchor-request.jsonGitHub ↗
{
"seal_hash": "sha256:...",
"seal_type": "uso_instance",
"subject_type": "uso_id",
"subject_id": "0196F...",
"signal_id": "sssr:compute_method_registry.created_at",
"trustgate_event_id": "tg_evt_...",
"execution_audit_event_id": "exec_evt_...",
"framework_context": ["ESRS", "CSRD"],
"metadata": {
"reporting_period": "2026-Q1",
"disclosure_id": "E1-6"
},
"updated_by": "cto@viroway.com"
}

Response

fabric-anchor-response.jsonGitHub ↗
{
"ok": true,
"anchor_id": "anc_0196F...",
"fabric_tx_id": "...",
"seal_hash": "sha256:...",
"anchor_status": "active"
}

E.9.2. GET /admin/fabric/anchors/:anchor_id

Reads anchor by ID.

Response

anchor-read-by-id-response.jsonGitHub ↗
{
"ok": true,
"anchor": {
"anchor_id": "anc_0196F...",
"seal_hash": "sha256:...",
"subject_type": "uso_id",
"subject_id": "0196F...",
"anchor_status": "active",
"created_at": "2026-04-28T09:07:16Z",
"created_by_org": "VirowayMSP"
}
}

E.9.3. GET /admin/fabric/anchors/by-seal/:seal_hash

Reads anchor by seal hash.

Because seal_hash may contain : characters, the API should URL-encode the path segment or use a query parameter.

Recommended safer endpoint:

GET /admin/fabric/anchors/by-seal?seal_hash=sha256%3A...


E.9.4. GET /admin/fabric/anchors/by-subject

Reads latest anchor for a subject.

GET /admin/fabric/anchors/by-subject?subject_type=uso_id&subject_id=0196F...


E.9.5. POST /admin/fabric/anchors/verify

Verifies ZAYAZ internal seal against Fabric anchor.

Request

verify-internal-seal-request.jsonGitHub ↗
{
"subject_type": "uso_id",
"subject_id": "0196F..."
}

Response

verify-internal-seal-response.jsonGitHub ↗
{
"ok": true,
"verification_status": "valid",
"internal_seal_hash": "sha256:...",
"fabric_seal_hash": "sha256:...",
"anchor_id": "anc_0196F...",
"fabric_tx_id": "...",
"verified_at": "2026-04-28T09:12:00Z"
}

E.9.6. POST /admin/fabric/anchors/supersede

Creates new anchor and supersedes an old anchor.

Request

create-new-anchor-request.jsonGitHub ↗
{
"old_anchor_id": "anc_0196F...",
"new_seal_hash": "sha256:...",
"subject_type": "uso_id",
"subject_id": "0196F...",
"reason": "Corrected disclosure after approved restatement.",
"updated_by": "cto@viroway.com"
}

E.9.7. POST /admin/fabric/anchors/revoke

Revokes an invalid anchor.

Request

revoke-invalid-anchor-request.jsonGitHub ↗
{
"anchor_id": "anc_0196F...",
"reason": "Anchor created from invalid seal hash during test.",
"updated_by": "cto@viroway.com"
}

E.10. Internal PostgreSQL Mirror Table

ZAYAZ should keep a local mirror of Fabric anchor metadata.

create-fabric-seal-anchor.sqlGitHub ↗
CREATE TABLE IF NOT EXISTS zar.fabric_seal_anchor (
fabric_seal_anchor_id bigint GENERATED ALWAYS AS IDENTITY PRIMARY KEY,

anchor_id text NOT NULL UNIQUE,
anchor_type text NOT NULL,

seal_hash text NOT NULL,
hash_algorithm text NOT NULL DEFAULT 'SHA-256',

subject_type text NOT NULL,
subject_id text NOT NULL,

uso_instance_id bigint REFERENCES zar.uso_instance(uso_instance_id),
uso_id text,

signal_registry_id bigint,
signal_id text,

trustgate_telemetry_id bigint REFERENCES zar.trustgate_telemetry_event(trustgate_telemetry_id),
trustgate_event_id text,

execution_audit_event_id text,
report_id text,
carbon_passport_id text,

zayaz_tenant_id text,
framework_context jsonb,
metadata jsonb,
metadata_hash text,

fabric_channel text NOT NULL,
fabric_chaincode text NOT NULL,
fabric_tx_id text,
fabric_block_number bigint,

anchor_status text NOT NULL DEFAULT 'active',
supersedes_anchor_id text,
supersession_reason text,
revoked_at timestamptz,
revocation_reason text,

anchored_at timestamptz NOT NULL DEFAULT now(),
verified_at timestamptz,
verification_status text,

status text NOT NULL DEFAULT 'active',
version text NOT NULL DEFAULT '1_0_0',
created_at timestamptz NOT NULL DEFAULT now(),
updated_at timestamptz NOT NULL DEFAULT now(),
updated_by text
);

CREATE UNIQUE INDEX IF NOT EXISTS ux_fabric_seal_anchor_seal_hash
ON zar.fabric_seal_anchor(seal_hash);

CREATE INDEX IF NOT EXISTS idx_fabric_seal_anchor_subject
ON zar.fabric_seal_anchor(subject_type, subject_id);

CREATE INDEX IF NOT EXISTS idx_fabric_seal_anchor_uso_id
ON zar.fabric_seal_anchor(uso_id);

CREATE INDEX IF NOT EXISTS idx_fabric_seal_anchor_signal_id
ON zar.fabric_seal_anchor(signal_id);

CREATE INDEX IF NOT EXISTS idx_fabric_seal_anchor_trustgate_event_id
ON zar.fabric_seal_anchor(trustgate_event_id);

CREATE INDEX IF NOT EXISTS idx_fabric_seal_anchor_report_id
ON zar.fabric_seal_anchor(report_id);

CREATE INDEX IF NOT EXISTS idx_fabric_seal_anchor_carbon_passport_id
ON zar.fabric_seal_anchor(carbon_passport_id);

COMMENT ON TABLE zar.fabric_seal_anchor IS
'Local PostgreSQL mirror of Hyperledger Fabric seal anchors. Stores metadata needed to verify ZAYAZ cryptographic seal hashes against externally anchored ledger records.';

E.11. Node API Integration Pattern

Use Fabric Gateway SDK from the ZAYAZ API service.

Fabric Gateway’s contract interface supports evaluateTransaction for read-only ledger queries and submitTransaction for state-changing ledger updates. 

Pseudocode

async function submitFabricCreateAnchor(anchor: SealAnchor): Promise<{
txId: string;
}> {
const gateway = await connectFabricGateway();
const network = gateway.getNetwork('zayaz-audit-anchor');
const contract = network.getContract('zayaz-seal-anchor');
const result = await contract.submitTransaction(
'CreateSealAnchor',
JSON.stringify(anchor),
);
return {
txId: result.toString(),
};
}
async function evaluateFabricAnchor(anchorId: string): Promise<SealAnchor> {
const gateway = await connectFabricGateway();
const network = gateway.getNetwork('zayaz-audit-anchor');
const contract = network.getContract('zayaz-seal-anchor');
const result = await contract.evaluateTransaction(
'GetSealAnchor',
anchorId,
);
return JSON.parse(result.toString());
}

E.12. Verification Flow


E.13. Privacy and Data Minimization

The Fabric anchor layer must be privacy-preserving.

Recommended rule:

Only hashes and non-sensitive identifiers are written to Fabric.

If metadata may reveal sensitive client context, store it in:

  • PostgreSQL only, or
  • Fabric Private Data Collections, where appropriate.

Fabric private data collections allow a subset of organizations on a channel to share private data while other organizations can still verify transaction integrity by hash. 


E.14. Endorsement Policy

Recommended endorsement policy:

OR('VirowayMSP.peer', 'AuditorMSP.peer')

For regulator-critical channels:

AND('VirowayMSP.peer', 'AuditorMSP.peer')

For multi-party CPI verification:

AND('ExporterMSP.peer', 'ImporterAuthorityMSP.peer')


E.15. What Should Not Be Anchored

Do not anchor:

  • every raw telemetry event
  • every intermediate execution event
  • full JSON payloads
  • personal data
  • commercially sensitive source data

Anchor:

  • final disclosure seals
  • CPI records
  • high-value assurance outputs
  • approved report packages
  • externally shared ESG metrics

E.16. Summary

The Fabric Anchor Layer gives ZAYAZ external proof without compromising internal performance or data privacy.

ZAYAZ computes truth.
Cryptographic sealing proves internal integrity.
Hyperledger Fabric anchors external trust.

Final principle:

Store evidence in ZAYAZ. Anchor proof on Fabric.


Final note

LayerWe have
SemanticsZARATHUSTRA
ExecutionZAYAZ
ValidationTrustGate
ProvenanceUSO
ReplayAudit Flow
Integrity🔐 Cryptographic sealing
Proof🔐 Hyperledger Fabric
Human access🧾 Auditor UI



GitHub RepoRequest for Change (RFC)