{"entry":{"fixtureId":"xchain-atomic-swap-v0","appSlug":"xchain-atomic-swap","appName":"Nockchain<->Base HTLC Atomic Swap","reportId":"lab_xchain-atomic-swap-v0_20260610225855218","generatedAt":"2026-06-10T22:58:55.218Z","status":"pass","jsonPath":"/bundle/server-functions/default/.nocklab/xchain-atomic-swap.report.json","markdownPath":"/bundle/server-functions/default/.nocklab/xchain-atomic-swap.report.md","reportHash":"sha256:e2a3982bb5339c7ef6d373570b7113c51f67ee906192ec7b3e670ff83e84d2a1","snapshotRoot":"9dc19dfeda68ca5b","badgeCandidate":{"id":"badge-candidate-xchain-atomic-swap","label":"Nockchain<->Base HTLC Atomic Swap Verification Candidate","reportSlug":"xchain-atomic-swap","fixtureId":"xchain-atomic-swap-v0","status":"ready","evidenceKind":"model-attested","statusReDerived":"pass","statusConsistent":true,"kernelHash":null,"kernelVerified":false,"baseDeploymentHash":null,"baseVerified":false,"signatureStatus":"unsigned","evidence":{"reportHash":"sha256:e2a3982bb5339c7ef6d373570b7113c51f67ee906192ec7b3e670ff83e84d2a1","snapshotRoot":"9dc19dfeda68ca5b","invariantPacks":[]}},"stepsPassed":1,"stepsTotal":1,"invariantsPassed":3,"invariantsTotal":3,"alertsTriggered":0,"snapshotsCaptured":2,"adapterObservationCount":0,"invariantPackCount":0},"report":{"reportId":"lab_xchain-atomic-swap-v0_20260610225855218","fixtureId":"xchain-atomic-swap-v0","generatedAt":"2026-06-10T22:58:55.218Z","app":{"name":"Nockchain<->Base HTLC Atomic Swap","slug":"xchain-atomic-swap","version":"0.0.1","kernel":"xchain-atomic-swap-model"},"environment":{"mode":"mock-fakenet","grpcEndpoint":"n/a","fakenetCommand":"model","notes":["Models a CORRECT cross-chain HTLC: both legs lock the SAME shared preimage, each under its own native hash.","Nockchain leg uses %hax = Tip5 (hoon/common/tx-engine-1.hoon); Base leg uses sha256 (an EVM precompile). The commitments DIFFER (Tip5 != sha256) but both derive from the one shared preimage, so revealing it unlocks both legs.","Timelocks are safe: the first-funded (Nockchain) refund window outlasts the Base claim window, so the counterparty cannot refund and still claim.","Honest limit: a single-process MODEL of two chains (model-attested), not live execution. The Tip5 commitment is opaque here (Tip5 is not computable in JS)."]},"summary":{"status":"pass","stepsPassed":1,"stepsFailed":0,"invariantsPassed":3,"invariantsFailed":0,"alertsClear":0,"alertsTriggered":0,"snapshotsCaptured":2,"durationMs":17,"expectRejected":false,"rawStatus":"pass"},"invariantPacks":[],"steps":[{"id":"reveal-and-claim","type":"bridge","title":"Reveal the shared preimage -> both legs claimed","status":"pass","expectation":"xchain.settlement.0 == claimed","observed":"claimed","beforeHash":"6269975ab9195f51","afterHash":"9dc19dfeda68ca5b","stateDiffs":[{"path":"xchain.settlement","before":"[\"locked\",\"locked\"]","after":"[\"claimed\",\"claimed\"]"}],"durationMs":19}],"invariants":[{"id":"hashlock-algo-match","title":"Each HTLC leg locks the shared preimage under a hash its own chain can compute (Tip5 vs sha256)","severity":"critical","status":"pass","observed":"all 2 leg(s) lock the shared preimage under a chain-computable hash; commitments distinct","expected":"each HTLC leg locks the shared preimage under a hash its own chain can compute, with distinct per-chain commitments, under xchain"},{"id":"timelock-ordering","title":"First-funded refund window outlasts the second leg's claim window (no free option)","severity":"critical","status":"pass","observed":"first-funded nockchain=200 > all other legs","expected":"refund timelock on the first-funded leg > claim window on every other leg under xchain"},{"id":"atomic-settlement","title":"Both legs claimed or both refunded (never one-sided)","severity":"critical","status":"pass","observed":"atomic: all 2 leg(s) claimed","expected":"terminal settlement is all-claimed or all-refunded (no mix, no stuck-locked) under xchain.settlement"}],"alerts":[],"adapterObservations":[],"stateSnapshots":[{"label":"Initial state","stateHash":"6269975ab9195f51","state":{"xchain":{"preimage":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","legs":[{"chain":"nockchain","hashAlgo":"tip5","commitment":"t1p5cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","derivedFromSharedPreimage":true,"timelockBlocks":200,"fundsFirst":true},{"chain":"base","hashAlgo":"sha256","commitment":"e0e77a507412b120f6ede61f62295b1a7b2ff19d3dcc8f7253e51663470c888e","derivedFromSharedPreimage":true,"timelockBlocks":100,"fundsFirst":false}],"settlement":["locked","locked"]}}},{"label":"After reveal-and-claim","stateHash":"9dc19dfeda68ca5b","state":{"xchain":{"preimage":"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa","legs":[{"chain":"nockchain","hashAlgo":"tip5","commitment":"t1p5cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc","derivedFromSharedPreimage":true,"timelockBlocks":200,"fundsFirst":true},{"chain":"base","hashAlgo":"sha256","commitment":"e0e77a507412b120f6ede61f62295b1a7b2ff19d3dcc8f7253e51663470c888e","derivedFromSharedPreimage":true,"timelockBlocks":100,"fundsFirst":false}],"settlement":["claimed","claimed"]}},"stepId":"reveal-and-claim"}],"stateDiffs":[{"path":"xchain.settlement","before":"[\"locked\",\"locked\"]","after":"[\"claimed\",\"claimed\"]"}],"nextActions":["Replace mock poke and peek execution with local fakenet adapter calls.","Replace command-backed fakenet metadata probes with stable gRPC-native probes once node surfaces are available.","Persist generated reports under a project workspace.","Add app-specific invariant packs as the NockApp interface stabilizes."]},"markdown":"# ✅ Nockchain<->Base HTLC Atomic Swap Lab Report\n\n> **PASS** — 1/1 steps · 3/3 invariants · 0 alerts · 17ms\n\n| Field | Value |\n| --- | --- |\n| Report | `lab_xchain-atomic-swap-v0_20260610225855218` |\n| Fixture | `xchain-atomic-swap-v0` |\n| Status | ✅ pass |\n| Steps | 1 passed, 0 failed |\n| Invariants | 3 passed, 0 failed |\n| Alerts | 0 clear, 0 triggered |\n| Snapshots | 2 |\n\n## Steps\n\n- ✅ `reveal-and-claim` — claimed _(xchain.settlement.0 == claimed)_; 6269975ab9195f51 -> 9dc19dfeda68ca5b\n  - xchain.settlement: [\"locked\",\"locked\"] -> [\"claimed\",\"claimed\"]\n\n## Invariants\n\n- ✅ `hashlock-algo-match` — all 2 leg(s) lock the shared preimage under a chain-computable hash; commitments distinct _(expected each HTLC leg locks the shared preimage under a hash its own chain can compute, with distinct per-chain commitments, under xchain)_\n- ✅ `timelock-ordering` — first-funded nockchain=200 > all other legs _(expected refund timelock on the first-funded leg > claim window on every other leg under xchain)_\n- ✅ `atomic-settlement` — atomic: all 2 leg(s) claimed _(expected terminal settlement is all-claimed or all-refunded (no mix, no stuck-locked) under xchain.settlement)_\n\n## Alerts\n\n- No alert policies configured.\n\n## Adapter Observations\n\n- No adapter observations captured.\n\n## State Diffs\n\n- xchain.settlement: [\"locked\",\"locked\"] -> [\"claimed\",\"claimed\"]\n\n## Snapshot Timeline\n\n- Initial state: 6269975ab9195f51\n- After reveal-and-claim: 9dc19dfeda68ca5b\n\n","evidence":{"stateDiffCount":1,"snapshotCount":2,"alertCount":0,"triggeredAlertCount":0,"clearAlertCount":0,"triggeredCriticalAlertCount":0,"triggeredWarningAlertCount":0,"triggeredInfoAlertCount":0,"environmentMode":"mock-fakenet","grpcEndpoint":"n/a","environmentNoteCount":4,"nextActionCount":4,"firstNextAction":"Replace mock poke and peek execution with local fakenet adapter calls.","invariantPackCount":0,"invariantPackIds":[],"invariantPackDomains":[],"firstInvariantPackPath":"","changedPaths":["xchain.settlement"],"markdownPreview":"# ✅ Nockchain<->Base HTLC Atomic Swap Lab Report"}}