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:
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
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
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_eventgit_sha
The system:
- loads exact code versions
- replays transformations in order
- reproduces final output
Step 6 — Compare Results
| Check | Description |
|---|---|
| Output match | Recomputed output vs stored output |
| Hash validation | Input/output integrity |
| Trust consistency | Same TrustGate decision reproduced |
5. Example Replay Scenario
Input
{
"uso_id": "0196F...",
"csi": "MICE.InvoiceEmissions.OUTPUT.CO2E.1_0",
"origin_chain_codes": ["MIE12","TG3K7"]
}
Replay Result
{
"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
| Field | Purpose |
|---|---|
trustgate_event_id | Link between USO and validation |
policy_id | Governing rule |
validator_id | Validation logic |
trust_score | Confidence metric |
7. Execution Audit Layer
Execution audit events provide full replay fidelity.
Stored Information
| Category | Description |
|---|---|
| Input | Raw payload before processing |
| Output | Result after processing |
| Transformation | Operation performed |
| Engine | Executing artifact (CMI) |
| Context | Runtime metadata |
8. Guarantees
The replay system guarantees:
| Guarantee | Description |
|---|---|
| Determinism | Same input + same code → same output |
| Traceability | Full lineage from origin to output |
| Verifiability | Independent replay possible |
| Integrity | Hash validation across steps |
9. Failure Modes
| Failure | Meaning |
|---|---|
| Output mismatch | Code changed or data corrupted |
| Missing artifact | ZAR registry incomplete |
| Missing audit event | Incomplete logging |
| Trust mismatch | Validation logic drift |
10. Design Principles
- Separation of concerns
- USO = identity + lineage
- TrustGate = validation
- Audit = execution detail
- Replay over storage
- System prioritizes reproducibility over redundancy
- Deterministic architecture
- No hidden transformations
- 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:
| Field | Description |
|---|---|
| event_hash | SHA-256 hash of current event payload |
| previous_hash | Hash of prior event in chain |
| chain_hash | Combined hash (current + previous) |
Example
{
"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
| Layer | Storage |
|---|---|
| USO | stores seal_hash (optional reference) |
| TrustGate | references validation hash |
| execution_audit_event | stores chain-level hashes |
A.5. Verification Process
To verify integrity:
- Recompute all event hashes
- Rebuild the chain
- Compare final seal hash
If mismatch:
→ tampering or corruption detected
A.6. Optional Extensions
| Extension | Description |
|---|---|
| Digital signatures | Sign seal with private key |
| Blockchain anchoring | Store seal hash externally |
| Merkle trees | Batch verification for large datasets |
| Zero-knowledge proofs | Verify 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:
| Field | Description |
|---|---|
| trust_score | Final score |
| policy_id | Governing policy |
| validator_id | Validation logic |
| decision | pass / fail |
| reasoning | human-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:
| Endpoint | Purpose |
|---|---|
/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:
| Layer | Function | Scope |
|---|---|---|
| Cryptographic Sealing | Internal integrity and replay validation | Within ZAYAZ |
| Hyperledger Fabric | External trust and non-repudiation | Across 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
| Guarantee | Description |
|---|---|
| Integrity | Data has not been altered |
| Determinism | Same inputs reproduce same outputs |
| Replayability | Full 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
| Guarantee | Description |
|---|---|
| Non-repudiation | Data cannot be denied after anchoring |
| External trust | Independent 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.
Recommended use cases
- CSRD / ESRS disclosures
- Carbon Passport (CPI) outputs
- Regulatory submissions
- Inter-company data exchanges
- High-value ESG metrics
Not recommended
- 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:
| Layer | Function | Scope |
|---|---|---|
| Cryptographic Sealing | Internal integrity and replay validation | Within ZAYAZ |
| Hyperledger Fabric | External trust and non-repudiation | Across 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
| Guarantee | Description |
|---|---|
| Integrity | Data has not been altered |
| Determinism | Same inputs reproduce same outputs |
| Replayability | Full 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
| Guarantee | Description |
|---|---|
| Non-repudiation | Data cannot be denied after anchoring |
| External trust | Independent 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.
Recommended use cases
- CSRD / ESRS disclosures
- Carbon Passport (CPI) outputs
- Regulatory submissions
- Inter-company data exchanges
- High-value ESG metrics
Not recommended
- 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
- Execution produces audit events
- Hash chain is built internally
- Final seal_hash is generated
- seal_hash is anchored to Hyperledger Fabric
- 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
| Capability | Cryptographic Sealing | Hyperledger Fabric | Combined |
|---|---|---|---|
| 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
| Layer | Responsibility |
|---|---|
| Cryptographic Sealing | Builds internal hash chain and generates seal_hash |
| Hyperledger Fabric | Anchors seal_hash externally |
| ZAYAZ Verification API | Recomputes 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
E.3. Recommended Anchor Object
The Fabric ledger should store:
{
"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_idseal_hashseal_typesubject_idsubject_typecreated_at
Validation rules:
anchor_idmust not already existseal_hashmust not already exist as activeseal_hashmust match allowed hash format- submitter MSP must be allowed to anchor
anchor_statusmust start as active
E.5.2. GetSealAnchor
Reads an anchor by ID.
GetSealAnchor(anchor_id)
Returns:
{
"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:
{
"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
{
"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
{
"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
{
"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
{
"subject_type": "uso_id",
"subject_id": "0196F..."
}
Response
{
"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
{
"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
{
"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 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
| Layer | We have |
|---|---|
| Semantics | ZARATHUSTRA |
| Execution | ZAYAZ |
| Validation | TrustGate |
| Provenance | USO |
| Replay | Audit Flow |
| Integrity | 🔐 Cryptographic sealing |
| Proof | 🔐 Hyperledger Fabric |
| Human access | 🧾 Auditor UI |