%% FF For Future โ€” End-to-End Architecture (HAPPI/1.1) %% Render: https://mermaid.live (paste this block) or `mmdc -i architecture.mmd -o architecture.svg` flowchart TD subgraph User["๐Ÿ‘ค Analyser (Sepolia EOA)"] OPER[V>> / Rob / future analyst] end subgraph DApp["๐ŸŽจ Front-end / CLI"] CLI["happi.md run
cmd: rwa.analyse"] end subgraph HAPPI["๐Ÿ›ฐ HAPPI/1.1 Envelope (NDJSON event stream)"] ENV["{
v: 'happi/1.1',
cmd: 'rwa.analyse',
flags: { token, deal, model, ... }
}"] end subgraph Handler["๐Ÿค– GRIP / HAL handler (handler/rwa_analyse.py)"] VALID[validate envelope] READ[read data CID from contract] FETCH[fetch borrower JSON via IPFS gateway] COUNCIL["HAL council
(Claude + Gemini + Devil's Advocate)"] STAMP[stamp IDR provenance
data_cid ยท model ยท deal ยท envelope_id] PIN[pin IDR to Pinata] ANCHOR[setIdrCid via web3
updateRecord on contract] end subgraph Chain["โ›“ Sepolia Testnet"] CONTRACT["FinancialDataRegistry.sol
publishRecord / updateRecord
getCID / getRecord / getAllRecordIds"] DATAREC["data:thornfields-2026-q1
cid = bafkreig...
version: 1"] IDR1["idr:thornfields-2026-q1:claude-3.5
cid = bafy-idr-1
version: 1"] IDR2["idr:thornfields-2026-q1:gemini-1.5-pro
cid = bafy-idr-2
version: 1
(replay run โ€” different verdict)"] end subgraph IPFS["๐ŸŒ IPFS (content-addressed)"] DATAFILE[("data CID
borrower JSON
Thornfields Capital AG")] IDRFILE1[("IDR CID โ€” Claude
intent ยท data ยท reasoning ยท decision ยท outcome")] IDRFILE2[("IDR CID โ€” Gemini
(replay disagreement)")] end OPER --> CLI CLI --> ENV ENV --> VALID VALID --> READ READ -->|getCID record_id| CONTRACT CONTRACT --> DATAREC DATAREC -->|cid| FETCH FETCH -->|HTTP GET /ipfs/cid| DATAFILE DATAFILE -->|JSON| COUNCIL COUNCIL -->|completed event
+ IDR payload| STAMP STAMP --> PIN PIN -->|POST /pinning/pinFileToIPFS| IDRFILE1 IDRFILE1 -->|cid| ANCHOR ANCHOR -->|updateRecord IDR_KEY,cid| CONTRACT CONTRACT --> IDR1 %% Replay path โ€” second model, same data COUNCIL -.->|model=gemini-1.5-pro| STAMP STAMP -.-> PIN PIN -.-> IDRFILE2 IDRFILE2 -.-> ANCHOR ANCHOR -.-> IDR2 %% Verification path โ€” any third party with Sepolia RPC THIRD["๐Ÿง Third-party verifier
(investor / auditor / regulator)"] THIRD -->|getAllRecordIds| CONTRACT THIRD -->|getCID for each id| CONTRACT THIRD -->|fetch from IPFS
compare IDRs| IPFS classDef writeCall fill:#ffeaa7,stroke:#fdcb6e,stroke-width:2px; classDef readCall fill:#dfe6e9,stroke:#b2bec3,stroke-width:1px; classDef chain fill:#74b9ff,stroke:#0984e3,color:#fff,stroke-width:2px; classDef ipfs fill:#a29bfe,stroke:#6c5ce7,color:#fff,stroke-width:2px; class READ,FETCH readCall; class ANCHOR,PIN writeCall; class CONTRACT,DATAREC,IDR1,IDR2 chain; class DATAFILE,IDRFILE1,IDRFILE2 ipfs;