Falsification-as-a-Service: hash-committed datasets, proper-baseline templates, decision-rule-bound benchmarks, and signed audit-trail bundles.
Project description
FalsiFlyer
FalsiFlyer is the domain-agnostic methodology package extracted from the
ApotheQuery / Q-kernel-moat falsification audit trail (#7e–#7k).
It packages five hardening primitives so a new experiment can ship a defensible binary verdict in roughly the same shape as the eight Q-kernel falsifications:
- Hash-commit pre-registration —
falsiflyer.preregSHA-256 over a canonical (caller-declared) data payload, frozen with the schema version + decision rule + grid in a single JSON artifact.load_frozen_dataset()re-verifies the hash on read; mismatch raises. - Proper-baseline templates —
falsiflyer.baselinesGaussian,Proportional,Poisson,LogGaussian,Binomialnoise declarations with companion MAP/likelihood templates. Lets you instantiate a "literal-DGP Bayesian" baseline likeMAP_Proportionalwithout re-deriving it. - Decision-rule-bound harness —
falsiflyer.harness"Test estimator must beat each baseline by ≥X% on at least Y of N stress cells." The rule is serialized into the dataset and checked verbatim by the runner. No post-hoc threshold tuning. - Diagnostic-on-disagreement template —
falsiflyer.diagnosticWhen a decision is borderline or surprising, split the cohort by a binary attribute and re-score. Generalizes theclipped vs unclippeddiagnostic that produced the #7j → #7k pivot. - Audit-trail bundle —
falsiflyer.auditInterchangeable kernel slot + byte-identical anchor pin (file path, line number, SHA-256 of the file) + falsification record ledger.
Status (2026-05-06)
Initial standup is complete. The package implements all five primitives, ships two worked-example adapters in two distinct domains:
adapters/q_kernel_tdm.py— pharmacokinetic decay-rate falsification (#7j/#7k Q kernel-moat port), 27 cells × 32 subjects, FAIL verdict parity-checked against the recorded benchmark.adapters/impax_signal_disc.py— non-PK frequency-identification falsification, 27 cells × 32 subjects (signal+Gaussian-noise traces), PASS verdict on a continuous-frequency stub estimator vs three candidate-restricted classical baselines.
Both adapters use the same five-primitive shell, demonstrating the domain-portability claim. 47 self-contained tests + 1 nyxnet-gated parity test, plus 3 golden-replay fixtures pinning the q_kernel_tdm verdict and per-cell baseline rel-err.
Parity for q_kernel_tdm: running
nyxnet.questimator.estimate_gamma(method='questimator') through the
FalsiFlyer harness reproduces the recorded FAIL verdict and the exact
per-baseline pass counts (raw_NCA: 12, stderr_Shrunk_NCA: 9, MAP_Bayesian: 6, MAP_Proportional: 3). The dataset SHA differs from
the original because the original generator's hash routine and FalsiFlyer's
canonical_hash are independent re-implementations of the same scheme;
the data bytes are identical.
Sibling to gh_eval
FalsiFlyer and gh_eval are independent. gh_eval is the Goodhart-Hardened
Evaluator (composable scoring primitives for OpenEvolve programs);
FalsiFlyer is the pre-registration and decision-rule shell that wraps an
outside scientific claim. They share zero code and zero dependencies.
Quick start
from falsiflyer import (
DecisionRule, freeze_dataset, load_frozen_dataset,
Estimator, Harness,
)
# 1. pre-register
ds, path = freeze_dataset(
schema_version="my_experiment_v1",
cells=[...],
decision_rule=DecisionRule(
test_estimator="my_test",
baselines=["baseline_a", "baseline_b"],
tightening_threshold=0.15,
pass_fraction=2/3,
stress_predicate="n in {2,3} AND CV in {0.20,0.30}",
),
hash_fields=("t", "F_hat", "N_shot"),
cell_param_keys=["k_pop", "n_samples", "cv"],
out_path="frozen.json",
)
# 2. (separately, AFTER freeze) run benchmark
ds = load_frozen_dataset("frozen.json") # re-verifies SHA-256
harness = Harness(
estimators={
"my_test": my_estimator,
"baseline_a": baseline_a,
"baseline_b": baseline_b,
},
)
result = harness.run(ds)
print(result.verdict.verdict_pass, result.verdict.n_pass_each_baseline)
Worked example A: q_kernel_tdm (#7j / #7k)
The shipped adapter adapters/q_kernel_tdm.py is a self-contained port
of the single-rate TDM falsification flow that produced the #7j → #7k
pivot. It exposes:
| Function | Purpose |
|---|---|
build_dataset |
Generate + freeze the 27-cell / 12-stress / 864-subj dataset |
build_harness |
Register the four classical baselines + cohort-prior builder |
The proprietary kernel (raw_Q) is plugged in by the caller; the
adapter itself imports nothing from nyxnet.
Demo runners:
# All-five-primitives end-to-end demo with a stub raw_Q
PYTHONPATH=. python3 examples/walkthrough_7j_to_7k.py
# Real-kernel parity check vs the recorded #7k benchmark
PYTHONPATH=FalsiFlyer:commercialization/path_c_nyxnet \
python3 examples/parity_check_7k.py
Worked example B: impax_signal_disc (signal-discrimination)
The second adapter adapters/impax_signal_disc.py ports a non-PK claim
through the same five primitives: identifying the dominant pure-tone
frequency in a noisy time-series. Each subject is a 256-sample signal
at 128 Hz with a continuous true frequency drawn log-uniformly from
[2 Hz, 32 Hz] and Gaussian noise scaled by SNR.
Three classical baselines all operate on a discrete candidate grid (so they incur an irreducible discretization rel-err that a continuous estimator can in principle beat):
| Baseline | Method |
|---|---|
raw_periodogram |
FFT magnitude peak → nearest candidate |
raw_matched_filter |
Coherent sin/cos correlation, argmax over candidates |
raw_bandpass_energy |
Per-candidate Goertzel-style narrowband energy |
Cell grid: SNR ∈ {0.5, 1.0, 5.0} × n_bins ∈ {4, 16, 64} × seed-fam ∈
{101, 211, 401} = 27 cells × 32 subjects. Stress predicate:
snr ≤ 1.0 AND n_bins ≥ 16 (12 stress cells).
Decision rule: tightening_threshold=0.30, pass_fraction=2/3,
metric=median_rel_err. Test estimator name: impax_classical.
Demo runners:
# Stub-kernel walkthrough (continuous-frequency parabolic refinement)
PYTHONPATH=. python3 examples/walkthrough_impax.py
# → VERDICT: PASS, 12/12 stress cells, all three baselines beaten
# Real-kernel parity check (blackbox.impax.impax.scanner.ImpaxFrequencyScanner)
PYTHONPATH=FalsiFlyer:blackbox/impax \
python3 examples/parity_check_impax.py
# → VERDICT: FAIL, 0/12 stress cells passing
Real-kernel result (informational): When the actual proprietary
ImpaxFrequencyScanner (broadband-detection + binary frequency search,
backed by ImpaxSensor's Nyx-dynamics anomaly score) is plugged in, it
fails the decision rule on this metric. Per-cell median rel-err
ranges 0.10–0.64 for impax vs 0.01–0.09 for matched-filter on stress
cells. This is a clean, reproducible falsification of a narrowly scoped
claim ("Impax beats classical on continuous-frequency rel-err with a
discrete candidate grid"). It does not contradict the existing 43x
classical-vs-quantum claim in Quasmology/sensing_comparison/, which
uses a different metric (anomaly-score discrimination on binary
signal-vs-noise). The two results probe different falsifiable claims.
Tests
cd FalsiFlyer
pytest # 47 pass + 1 skip
PYTHONPATH=.:../commercialization/path_c_nyxnet pytest # 48 pass
Test layout:
tests/
├── test_prereg.py hash determinism, mutation detection, freeze/load round-trip
├── test_baselines.py 5 noise models: log-likelihood + simulate
├── test_harness.py PASS/FAIL verdict, validation, cohort builders, output writes
├── test_diagnostic.py disagreement-split correctness, only_stress filter
├── test_audit.py anchor drift, kernel slot, ledger, decision-rule hash
├── test_impax_signal_disc.py impax adapter: shape, hash, oracle PASS, no-leakage
├── test_golden_q_kernel_tdm.py golden-replay (7j baselines, 7k baselines, 7k questimator)
└── golden/
├── q_kernel_tdm_7j_baselines.json — pins #7j SHA + per-cell baseline median rel-err
├── q_kernel_tdm_7k_baselines.json — pins #7k SHA + per-cell baseline median rel-err
├── q_kernel_tdm_7k_questimator.json — pins FAIL verdict + per-baseline pass counts
└── _generate_fixtures.py — manual regenerator (audit-trail step)
The questimator-replay test is skipif when nyxnet is not on the
path, so the package is fully self-testable in a clean environment.
File layout
FalsiFlyer/
├── pyproject.toml setuptools, deps numpy + pydantic
├── README.md this file
├── falsiflyer/ core library (zero subvurs imports)
│ ├── __init__.py public re-exports
│ ├── errors.py FalsiFlyerError + 3 leaves
│ ├── types.py Subject, Cell, Dataset, *Score, Verdict
│ ├── prereg.py canonical_hash, freeze, load, DecisionRule
│ ├── baselines.py 5 NoiseModels + BaselineLibrary
│ ├── harness.py Estimator, Harness, evaluate_decision_rule
│ ├── diagnostic.py DisagreementSplit, run_split_diagnostic
│ ├── audit.py Anchor, KernelSlot, Record, Ledger
│ └── report.py render_markdown_report
├── adapters/
│ ├── q_kernel_tdm.py #7j/#7k worked example (PK domain)
│ └── impax_signal_disc.py signal-discrimination worked example (non-PK)
├── examples/
│ ├── walkthrough_7j_to_7k.py q_kernel_tdm five-primitives demo (stub raw_Q)
│ ├── parity_check_7k.py real questimator vs recorded benchmark
│ ├── walkthrough_impax.py impax_signal_disc five-primitives demo (stub kernel)
│ └── parity_check_impax.py real ImpaxFrequencyScanner through harness
├── tests/ pytest, 48 pass (47 + 1 gated)
└── docs/
├── ARCHITECTURE.md 5-primitive data flow + design invariants
└── ADAPTER_GUIDE.md 10-step guide to porting a new experiment
Provenance
Extracted from:
commercialization/path_c_nyxnet/tools/q_kernel_tdm_dataset_gen.pycommercialization/path_c_nyxnet/tools/q_kernel_tdm_dataset_gen_7k.pycommercialization/path_c_nyxnet/tools/benchmark_q_kernel_tdm.pycommercialization/path_c_nyxnet/tools/benchmark_q_kernel_tdm_7k.pycommercialization/path_c_nyxnet/tools/diagnose_7j_n3_catchup.py
Methodology source: ApotheQuery_BRIEF.txt (#7e–#7k), product spec:
POST_KERNEL_MOAT_PRODUCT_DIRECTIONS.txt Section 6.2 (Direction 1,
Falsification-as-a-Service).
Next steps (post-standup)
- Pharma-analytics buyer pilot (POST_KERNEL_MOAT §6.3) — package
FalsiFlyer+q_kernel_tdmadapter as the live demo for the first 12-week paid pilot. Second worked-example adapter— DONE (2026-05-06):adapters/impax_signal_disc.pyports a non-PK signal-discrimination claim through the same five primitives. Domain portability validated.Open-source release— DONE (2026-05-06): Apache-2.0,LICENSE/NOTICE/CONTRIBUTING.md/CHANGELOG.mdin place, GitHub Actions CI matrix on Python 3.9–3.12 × {core, audit, scipy} extras. Published as v0.2.0.Audit ledger durability spec— DONE (2026-05-06): hash chain + Ed25519 sign/verify infalsiflyer.audit, JSONL append-only format with cross-process chain check, full threat model indocs/AUDIT_LEDGER_SPEC.md. 25 audit tests, 65 total green.hash_data_payloadbyte parity (optional) — if the open-source release wants byte-identical SHA replay against the originalq_kernel_tdm_dataset_gen_7k.py, port that hash routine into alegacy_hashadapter mode. Not required for verdict parity.Impax parity demo— DONE (2026-05-06):examples/parity_check_impax.pyplugs the realblackbox.impax.impax.scanner.ImpaxFrequencyScannerinto the impax_signal_disc harness. The harness produces a FAIL verdict (0/12 stress cells), demonstrating the framework cleanly surfaces real-kernel falsification on a different domain than the original #7e–#7k audit trail.
License
Apache License 2.0 — see LICENSE and NOTICE.
Copyright 2026 Mark Eatherly
Licensed under the Apache License, Version 2.0. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0.
Distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
The Apache 2.0 patent grant explicitly covers the hash-chain + Ed25519
audit-ledger construction in falsiflyer.audit. Contributors and
downstream users get the same patent license under inbound=outbound.
For threat-model questions about the audit ledger, see
docs/AUDIT_LEDGER_SPEC.md.
For contribution scope, see CONTRIBUTING.md.
For change history, see CHANGELOG.md.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file falsiflyer-0.2.1.tar.gz.
File metadata
- Download URL: falsiflyer-0.2.1.tar.gz
- Upload date:
- Size: 58.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
d21185ac7e5c896139659ccff657020445839db487c89c4d503ba46cb0187201
|
|
| MD5 |
b09b855bc14426d4fea3ab7bf7b5a205
|
|
| BLAKE2b-256 |
f562e9c80b43c09f39391a84f873b17ae359858d7c982df888b01b5729e76d90
|
File details
Details for the file falsiflyer-0.2.1-py3-none-any.whl.
File metadata
- Download URL: falsiflyer-0.2.1-py3-none-any.whl
- Upload date:
- Size: 46.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.13.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
811a92525e8a2bd819684fb95a30df00fd2c528187f5697c4de5ce32292f568f
|
|
| MD5 |
44c58b0ac071f9a3c950412a18255f29
|
|
| BLAKE2b-256 |
9200d740544bf38ca4b0de69806753189913caf0c2cf2304225ae6e3ba200343
|