Skip to main content

lookahead-free

Verifiable look-ahead-freedom for the value-independent fragment of data pipelines. Declare your pipeline as a temporally annotated DAG 鈥?reads with release times, windows with ends, PIT reads with cutoffs, decisions with decision times 鈥?and lf check proves, in linear time, that no decision consumes data that was not knowable yet. Python 3.11+, zero dependencies, Windows / Linux / macOS.

Status: v0.1 鈥?alpha. The model follows Fonseca (2026); expect the op kinds and CLI to grow.

Why this exists

Look-ahead bias is the quiet killer of backtests: a pipeline that computes today's signal from data that only becomes available at 16:00, then "decides" at 15:00, looks great and lies. The usual defenses are heuristics 鈥?reviewers eyeballing code, linters matching patterns. This tool is different: it checks a declarative description of the pipeline and gives an exact verdict on the fragment where exactness is possible.

Grounding. Fonseca (2026), "Look-Ahead-Freedom as Temporal Non-Interference" (arXiv:2607.04958, submitted to ACM TOSEM) proves that look-ahead-freedom is undecidable in general (螤鈦扳倎-hard when availability depends on data values), but admits a linear-time decidable type-effect system on the value-independent fragment 鈥?windowing, resampling, joins, point-in-time and vintage reads. This tool implements exactly that system:

  • every op carries a temporal bound (release / window end / PIT cutoff / decision time),
  • output availability is derived exactly (monotone: no op can produce a fact earlier than the facts it consumes),
  • decision availability is checked exactly: every input of a decision must be available at or before the decision time.

Honest boundary (stated, not hidden). Operations declared value_dependent: true are flagged at the heuristic boundary (P1): their temporal structure is still checked exactly, but for the operation itself no verifiable claim exists 鈥?Fonseca's undecidability result is precisely about value-dependent availability. The tool says so, in the report, every time.

Quick start

# install from PyPI (once published)
pip install lookahead-free

# or run without installing anything:
#   PYTHONPATH=src python -m lookahead_free --help

python examples/demo.py                    # clean pipeline passes, leaky one fails

lf check --pipeline examples/factor-pipeline.json
lf check --pipeline pipeline.json --json   # machine-readable verdict

Exit codes: 0 = no look-ahead in the value-independent fragment, 1 = at least one P0 temporal violation (or unresolvable DAG), 2 = usage error. Wire it into CI as a hard gate on every pipeline definition.

Pipeline format

A JSON object with a name and an operations list. Each op:

Field Meaning
op_id unique node id
kind read / window / resample / join / pit_read / vintage_read / transform / decision / write
inputs references to other ops 鈥?by op_id or by output name (dataflow semantics; ambiguous output names are rejected)
outputs data names this op produces
release (read) when the data becomes knowable
window_end (window/resample, required) end of the lookback window
read_cutoff (pit_read/vintage_read, required) the PIT cutoff
decision_time (decision, required) when the decision is made
value_dependent optional; marks ops in the undecidable fragment (agentic retrieval, value-conditional availability)
note free-form

Availability of an op's output = its explicit bound, or the maximum availability of its inputs. See examples/factor-pipeline.json for a complete factor pipeline (quotes 鈫?windows 鈫?PIT fundamentals 鈫?join 鈫?agentic retrieval 鈫?decision).

The checks

Check Severity What it proves
dag P0 inputs resolve (op_id or output name), no duplicate ids, no cycles
monotonicity P0 no op's bound is earlier than an input's availability (impossible availability)
decision_availability P0 every input of a decision is available at or before the decision time 鈥?the core look-ahead check
window_boundary P0 window/resample ops declare their window end
pit_reads P0 PIT/vintage reads declare their cutoff
heuristic_boundary P1 value-dependent ops present 鈫?structural checks exact, op semantics heuristic (per Fonseca's undecidability)
pipeline_shape P2 informational

Philosophy

Prices must be knowable; decisions must be honest; undecidability must be stated.

The reproducibility crisis in computational research is structural, and in quantitative finance it shows up first as leakage: point-in-time data discipline (Kelly et al., NBER w35247; Look-Ahead-Bench, arXiv:2601.13770) is now an industry-wide principle because look-ahead silently inflates alpha (Daniel, Sornette & Wohrmann 2008). What has been missing is a machine-checkable statement of compliance. lookahead-free makes the claim "this pipeline does not peek" a CI gate instead of an audit ritual 鈥?and where the theory says no proof exists, it says so instead of pretending.

Development

python -m pip install -e . pytest
python -m pytest

CI runs the full test suite on Ubuntu, Windows and macOS with Python 3.11 and 3.12. Issues are handled on weekends; pull requests are welcome.

Related work

Project family

Part of Foolproof Labs — a toolchain against self-deception in quantitative research:

License

MIT

Metadata

Release files for lookahead-free 0.1.1

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for lookahead-free 0.1.1
File Size Uploaded
lookahead_free-0.1.1.tar.gz 15.4 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for lookahead-free 0.1.1
File Interpreter ABI Platform
lookahead_free-0.1.1-py3-none-any.whl Python 3 none any Details

Total release size: 27.5 kB

Release files / lookahead_free-0.1.1.tar.gz

Download URL lookahead_free-0.1.1.tar.gz
Size 15.4 kB
Tags Source
SHA-256 checksum
How to use checksums
3fdb8044899ad03aa33147796823f314172dd5aadc3b952d3a3daad97ed5b290
BLAKE2b-256 checksum
How to use checksums
b330d418dd3a10a832f41ee1ac0d24469e5a7683a9f7618333b2d703873071ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release files / lookahead_free-0.1.1-py3-none-any.whl

Download URL lookahead_free-0.1.1-py3-none-any.whl
Size 12.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
84eb3042d19c59aa62f86d68c39adc229d0f1174425e5dc669ed6117ff66e437
BLAKE2b-256 checksum
How to use checksums
62621564fc43aa9f200f69c45fbb69872f0f6ae552a21947ed820f32f070838e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.11.15

Release history Release notifications | RSS feed

0.1.3

2 release files

0.1.2

2 release files

This release

0.1.1 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page