# MERIDIAN method and receipt specification

## Scope

MERIDIAN processes archived, calibrated GW150914 detector strain in the browser. It does not search unknown events, calculate detection significance, rerun full Bayesian parameter estimation, or infer a sky map from its measured time lag. Posterior histograms and the sky map are independently labeled published GWTC-1 reference data.

## Input and data provenance

H1 and L1 each contain 131,072 samples at 4,096 Hz, starting GPS 1126259447. The time reference is the catalogue GPS 1126259462.4, corresponding to 2015-09-14 09:50:45.400 UTC. The 32-second HDF5 originals, IEEE-754 float64 little-endian array conversions, and exact source URLs and SHA-256 hashes are included in `dist/data/manifest.json`. The website checks each binary input against that manifest before processing. The manifest is a published provenance record, not an independent digital signature by GWOSC.

The CBC injection veto passes for both files. Do not infer that every kind of hardware injection is absent: the L1 continuous-wave injection flag differs. The supplied data are used for a known-event educational replay.

## Browser engine 1.0.0

1. Reject non-finite samples and any input other than 32 seconds at 4,096 Hz.
2. Estimate a one-sided noise power spectral density with 4,096-sample Hann windows and a 2,048-sample hop. Subtract each segment mean; divide squared FFT magnitude by `sampleRate * sum(window²)`, double positive non-Nyquist bins, then average the accepted periodograms. Exclude segments overlapping event GPS ±1 second. This yields 57 accepted noise segments.
3. Subtract the full-series mean and apply a Tukey taper with alpha 0.25. Compute a full-length radix-2 FFT.
4. If whitening is enabled, interpolate the noise PSD linearly to each FFT bin and divide by `sqrt(PSD * sampleRate / 2)`. A small numerical floor avoids division by zero.
5. Apply unit gain within the selected frequency band. Extend the lower and upper edges with 5 Hz cosine transitions. With line suppression enabled, set gain to zero within 1 Hz of 60, 120 and 180 Hz and transition to full gain at 2 Hz. Apply symmetric weights to positive and negative frequencies, then inverse FFT.
6. Normalize each processed detector series by its own RMS over [−12, −2] seconds relative to event GPS. Raw trace plots remain calibrated strain in units of 10⁻²¹. Normalization means the processed amplitude is not an astrophysical strain-amplitude estimate.
7. Compute signed normalized dot-product correlation over H1 times [−0.15, +0.05] seconds while shifting L1 by sample offsets up to ±10 ms. Select the largest absolute correlation. A negative displayed lag means L1 is earlier than H1: `L1(t + lag)` aligns with `H1(t)`. Sample spacing is 0.244140625 ms. This is a local waveform diagnostic using a known event window, not a full likelihood-based arrival-time posterior.
8. The reported RMS ratios compare the event window with the off-source normalization window. They are not matched-filter SNR and do not establish a false-alarm probability.
9. The H1 spectrogram uses 256-sample Hann windows and a 32-sample hop. Its colors are relative short-time Fourier power in decibels. It is not a Q-transform. The diagram spans 0–512 Hz; a selected wider filter is still applied to the underlying signal.

The JavaScript engine is the exact implementation used by both the browser and `npm run replay`. Its source hash is included in every report. `dist/downloads/build_reference.py` provides an independent SciPy comparison and prepares the published posterior and map products. Its PSD/window/filter settings differ, so its traces and diagnostic correlation are not expected to equal the browser engine bit for bit.

## Published inference views

The official GWTC-1 `Overall_posterior` sample set contains 8,350 samples. Masses in the posterior file are detector-frame masses; source-frame catalogue masses are different quantities. The interface shows medians and 5th/95th percentiles directly calculated from the archived samples. Effective spin is derived from the archived component spin magnitudes, tilts, and detector-frame masses.

The original sky map is a normalized HEALPix probability distribution with NSIDE 512 and NESTED ordering. The display samples it onto a one-degree equatorial grid, with right ascension increasing to the left. The 90% area is calculated from ranked original HEALPix pixels, not from the coarse display grid. It is a published localization, not the output of the browser correlation calculation.

## Reports and reproducibility

A JSON report has a committed `payload`, a `reportHash`, and optional signature/anchor receipts. The payload includes input provenance, exact engine identity, processing configuration, computed diagnostics, and processed waveform samples rounded to six decimal places. The creation timestamp is informational and outside the committed payload.

`afterlight-sorted-json-v1` recursively sorts object keys lexicographically, preserves array order, serializes finite numbers and strings with JavaScript JSON serialization, and encodes the result as UTF-8. The SHA-256 of these exact bytes is the report hash. This is an application format; it does not claim full RFC 8785 implementation.

The verification view first recomputes the content hash, then independently recovers an attached EOA wallet signature. Reproduction only uses the application's known local dataset and engine, never a URL supplied by the uploaded report. Exact report hashes should reproduce in the same runtime. If mathematical library rounding differs between runtimes, the interface reports whether waveform samples and correlation agree within 0.00001 normalized units and the peak lag sample is unchanged. The command-line replay performs exact-hash comparison.

A self-consistent hash does not establish that a report is accurate. Reproduction checks are separate. The readable HTML export is a view of the report; keep the JSON for automated checks.

## Wallet and on-chain receipt protocol

MERIDIAN retains the existing version-1 report schema, canonicalization identifier, engine identity, local archive key, and anchor byte prefix. These legacy protocol identifiers are stable so saved reports, signatures, and chain records remain verifiable. New wallet statements begin with `MERIDIAN evidence receipt v1`; the verifier accepts the exact original `AFTERLIGHT evidence receipt v1` statement as well. No other label or statement is accepted. The signed statement remains outside the report payload, so this brand change does not alter report digests.

Signing uses an EIP-191 personal message containing the application identifier, report SHA-256, signer address, and a plain-language statement of purpose. The exact message and signature are saved outside the hashed payload. Verification recovers the signer locally with ethers `verifyMessage`. This supports EOA key signatures, not ERC-1271 contract-wallet signatures or an assertion of institutional identity.

The optional chain commitment is a transaction with `from == to == the wallet address`, transferred value 0, and input data equal to the UTF-8 bytes of `AFTERLIGHT:v1:sha256:` followed by the raw 32-byte report digest. No contract deployment is necessary. Gas is charged by the selected network. Base Sepolia is a testnet; Base is a mainnet. These are distinct explicit choices.

Before submitting, the app checks the wallet's selected chain and requires `eth_getCode(address, latest) == 0x`. Accounts with executable or EIP-7702 delegated code cannot use this self-call path. If a report already has a signature, the recording wallet must match that signer.

The verifier retrieves chain identity, transaction, receipt, and the block from the configured public RPC. It checks the sender, recipient, exact input bytes, zero value, successful status, and canonical block hash, matching transaction/receipt block numbers and indices, and the exact transaction hash at that position in the block. A submitted transaction is not called confirmed. An included transaction is not called finalized. A public RPC result is not an independently validated light-client proof. Receipt checks can be unavailable during an RPC outage; the local report and signature remain verifiable.

## Primary sources

- GWOSC strain release: https://gwosc.org/eventapi/html/GWTC-1-confident/GW150914/v3/
- GWOSC processing tutorial: https://gwosc.org/s/events/GW150914/GW150914_tutorial.html
- GWTC-1 posterior release: https://dcc.ligo.org/LIGO-P1800370/public
- GWTC-1 localization release: https://dcc.ligo.org/LIGO-P1800381/public
- Base networks: https://docs.base.org/get-started/connect-to-base
- EIP-191: https://eips.ethereum.org/EIPS/eip-191
- EIP-7702: https://eips.ethereum.org/EIPS/eip-7702

## Workspace comparisons, audio, and saved reports

The comparison view uses the committed six-decimal waveform samples from two reports of the same event and engine. Both traces share the same plot window, time reference, detector choice and amplitude scale. It does not align the two configurations to one another or independently rescale their plotted peaks. Each run retains the engine’s own off-source RMS normalization. Table changes are current minus baseline. These are filter-sensitivity diagnostics, not a significance test.

Audio is an audification of the current processed detector array from approximately −0.6 to +0.3 seconds. Linear interpolation resamples the 4,096 Hz array to the browser audio device’s sample rate. A common peak scale limits playback amplitude to 0.25, with 10 ms endpoint fades. Recorded-speed playback preserves timing and frequency; half-speed playback doubles duration and lowers pitch by an octave. These listening transformations never enter the scientific report or its hash. Audio is not an air-pressure recording of a black hole.

The browser archive holds up to 20 unique report digests using local storage. It checks stored content hashes and signatures when loading. Reopening a report recalculates its inputs; only an exact reproduction adopts its saved report as the current exact result. A within-tolerance imported result is preserved separately from the newly calculated digest. Existing receipts take precedence when the same digest is rerun or imported; a compatible missing signature or chain receipt can be added, but different wallet identities are not merged. Signed payloads and the numerical engine remain version 1.0.0.

Settings links encode only frequency edges, whitening and line suppression. They cause a new local computation and do not carry a report, signature, chain receipt, or cloud-storage identifier. The browser archive is not an append-only ledger, and its timestamps are local metadata. The independent on-chain transaction is the network record. Saved inclusion metadata is historical: reopening a run prompts a new chain check rather than treating a previous lookup as current finality.

The bundled posterior and sky-display JSON are checked against `data/reference-integrity.json` before rendering. This detects inconsistent or damaged releases; it is not an external signature by the scientific data publisher.

Audio implementation reference: https://developer.mozilla.org/en-US/docs/Web/API/BaseAudioContext/createBuffer

## Numerical implementation agreement

`verify_numerics.py` independently implements the browser engine’s documented recipe with NumPy and SciPy. It uses SciPy’s periodogram density scaling on the accepted symmetric Hann segments, SciPy’s symmetric Tukey taper, and the SciPy real FFT. Noise-window exclusion, filter transitions, normalization windows, and signed-lag conventions are deliberately the same mathematical specification.

The release check runs the JavaScript engine under the Node version recorded in the JSON record. It covers the three supplied frequency presets, the default band without whitening, the default band without line suppression, and the allowed 20–800 Hz frequency range. Each configuration compares both unrounded 3,686-sample displayed traces and the signed correlation curve with a maximum absolute tolerance of 1e-8. The reported diagnostics have already been rounded to six decimal places by JavaScript, so their numerical tolerance is 1e-6. Selected peak lag samples and accepted noise-segment counts must match exactly. These cases do not exhaust all possible custom configurations.

When verifying a downloaded report, the Python checker compares its committed waveform and diagnostics within the existing report tolerance of 1e-5, while requiring the same lag sample, timing grid, input provenance, event, and engine identity. A numerical pass does not verify the report’s content hash or wallet signature; those are separate checks in the JavaScript verifier.

This comparison can reveal differences between numerical implementations. It cannot independently establish the validity of shared modeling assumptions, discovery significance, or a Bayesian posterior. It is performed by the project and is not a third-party scientific audit.

Implementation references:
- https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.periodogram.html
- https://docs.scipy.org/doc/scipy/reference/generated/scipy.signal.windows.tukey.html

## Archive backup and receipt recovery

A `meridian.archive.v1` backup contains 1–20 reports. The application checks content hashes and optional EOA signatures and reruns every report with the bundled known input and engine. It compares the committed payload using the same 1e-5 waveform/rounded-metric tolerance documented above. All reports must pass before the existing archive is merged and written once. The archive is unchanged when a report fails, would exceed capacity, or cannot be stored. Exact duplicate digests in a backup are rejected. Existing compatible receipts take precedence, and the interface reports when incoming receipts were not adopted. The backup timestamp is informational and is not signed.

Recovering an existing network transaction reads its sender and requires the same digest, zero value, self-recipient, successful inclusion and canonical block position as normal verification. A report's existing signer or chain sender remains the required wallet identity. A pending transaction cannot be recovered as an included receipt. Recovery makes no new transaction and requires no wallet connection. An attached receipt can be rechecked from the UI or the standalone `verify-chain.mjs` command.
