# Show HN: PhaseProbe – Find simulation transitions and turn them into tests

> Source: <https://github.com/aliengineering-byte/phaseprobe>
> Published: 2026-08-01 23:12:56+00:00

Find a simulation behavior boundary. Preserve it as a replay. Turn it into a test.

Maintaining a simulation is risky when a tiny parameter or initial-condition change can cross a qualitative boundary while ordinary numeric assertions still look plausible. PhaseProbe runs a bounded, deterministic search, records exactly what it tested, and emits an offline report plus an executable pytest regression.

``` bash
$ python -m pip install .
$ phaseprobe scan --example logistic
QUALITATIVE TRANSITION FOUND

Model: logistic-map
Search dimension: r
Baseline regime: period-2
Changed regime: period-4
Replay: .phaseprobe/runs/<run-id>/replay.json

$ phaseprobe generate-test .phaseprobe/runs/<run-id>/replay.json
$ python -m pytest -q tests/generated
1 passed
```

No API key, LLM, GPU, Docker, account, telemetry, network connection, or hosted service is required at runtime. PhaseProbe 0.1.0 has no third-party runtime dependencies.

Requires Python 3.10 or newer on Windows or Linux.

```
python -m pip install .
phaseprobe scan --example logistic
phaseprobe replay .phaseprobe/runs/<run-id>/replay.json
phaseprobe generate-test .phaseprobe/runs/<run-id>/replay.json
python -m pytest -q tests/generated
phaseprobe report .phaseprobe/runs/<run-id>
```

Replace `<run-id>`

with the directory printed by `scan`

. The scan returns `0`

when it successfully finds a transition. Add `--fail-on-finding`

only when a finding should fail CI.

The quick-start evidence is empirical: the built-in classifier finds a finite-time period-2/period-4 bracket for the logistic map, performs bounded binary refinement, repeats both endpoints, saves trace hashes and a versioned fixture, and generates a fixed pytest template. It does not claim an exact bifurcation point.

| command | job | normal success |
|---|---|---|
`scan` |
Bounded one-dimensional parameter scan, adjacent class-change detection, and stable bracket refinement | Finding or no finding, exit `0` |
`perturb` |
Baseline/perturbed twin runs over bounded initial-state changes | Finding or no finding, exit `0` |
`check` |
Execute a declared configuration policy for CI | Exit `1` only when policy fails |
`replay` |
Validate fixture integrity and re-execute model, parameters, seed, initial state, tolerances, and retention | Matching class and exact retained trace hashes |
`generate-test` |
Validate and copy a fixture into a non-extensible pytest template | Executable test under `tests/generated/` |
`report` |
Regenerate terminal, versioned JSON, and self-contained offline HTML evidence | Local report files |

Common options:

```
phaseprobe scan --config examples/configs/logistic-scan.json
phaseprobe perturb --example lorenz --json
phaseprobe check --example predator-prey
phaseprobe scan --example logistic --fail-on-finding
```

Exit codes are stable: `0`

completed, `1`

declared policy or explicit `--fail-on-finding`

, `2`

invalid input/configuration, `3`

numerical failure, and `4`

internal PhaseProbe defect.

| example | command | positive evidence | negative control | direct technical source |
|---|---|---|---|---|
| Logistic map | `phaseprobe scan --example logistic` |
Finite-time period-2 to period-4 classification bracket | `--example logistic-negative` stays period-2 over its declared range |
|

`phaseprobe perturb --example lorenz`

[Lorenz, 1963](https://journals.ametsoc.org/view/journals/atsc/20/2/1520-0469_1963_020_0130_dnf_2_0_co_2.xml)`phaseprobe check --example predator-prey`

[Lotka, 1920](https://doi.org/10.1073/pnas.6.7.410)`phaseprobe perturb --example toggle`

[Gardner, Cantor & Collins, 2000](https://www.nature.com/articles/35002131)Each configuration records the seed, fixed integration/iteration settings, tolerances, burn-in, observation window, classification rule, refinement rule, invalid-state policy, and trace cap. See [examples/README.md](/aliengineering-byte/phaseprobe/blob/main/examples/README.md) for equations and interpretation.

On 2026-08-01 with CPython 3.12.13 on Windows, the instrumented logistic quick-start scan completed in 10.114 seconds with a 34.81 MiB peak process-tree working set. All eight positive/negative example commands completed in 12.238 seconds. The final 38-test suite with branch coverage completed in 64.86 seconds at 87.92% coverage. These are observations from one local run, not cross-machine performance claims; the generated transcript is in [assets/demo-session.txt](/aliengineering-byte/phaseprobe/blob/main/assets/demo-session.txt).

Every execution is bounded under `.phaseprobe/runs/<run-id>/`

:

```
run.json       complete versioned evidence
findings.json  compact finding or negative result
replay.json    schema-versioned integrity-protected fixture
trace.jsonl    capped baseline/changed retained points
report.html    self-contained offline report
manifest.json  sizes and SHA-256 hashes
```

Model names used for generated test paths are sanitized. The generated source comes from a fixed template; configuration strings never become executable Python.

| existing category | established strength | PhaseProbe’s narrower job |
|---|---|---|
| Solvers such as SciPy | Integrate differential equations with mature numerical methods | Consume an adapter’s trajectories and preserve a discovered qualitative boundary as test evidence |
| Property-based testing such as Hypothesis | Generate and shrink broad input domains | Search declared simulation dimensions with model-specific observables and classes |
| Bifurcation/attractor tools such as AUTO, PyDSTool, and Attractors.jl | Deep continuation, bifurcation, attractor, and basin analysis | Lightweight black-box numerical brackets plus replay and pytest materialization |
| Sensitivity tools such as SALib | Quantify input contributions to output variation | Find a reproducible qualitative predicate change |
| Simulation environments such as Mesa, NetLogo, cadCAD, and Golly | Build, run, and explore models | Test adapters without becoming another simulation environment |

The evidence-backed audit is in [PRIOR_ART.md](/aliengineering-byte/phaseprobe/blob/main/PRIOR_ART.md).

Adapters implement a small typed protocol:

```
class ModelAdapter(Protocol):
    name: str
    identity: str
    dimensions: tuple[str, ...]

    def initial_state(self, config, seed): ...
    def step(self, state, parameters, dt): ...
    def observe(self, state): ...
    def classify(self, trace, tolerances): ...
    def invariants(self, trace, parameters, tolerances): ...
```

The explicit serializable state tuple makes bounded perturbation, invalid-value detection, trace hashing, and replay straightforward. See [ARCHITECTURE.md](/aliengineering-byte/phaseprobe/blob/main/ARCHITECTURE.md) for extension guidance.

PhaseProbe uses these terms deliberately:

- finite-time trajectory divergence: measured separation over the recorded window;
- sensitive-dependence evidence: repeatable finite-time divergence under a declared small perturbation, not by itself a proof of chaos;
- numerical instability: behavior attributable to the numerical method or step size;
- invariant violation: a declared conservation or boundedness rule failed;
- qualitative regime change: the adapter’s declared classifier changed;
- bifurcation evidence: a numerical class-change bracket, not an exact bifurcation point;
- invalid integration: NaN, infinity, overflow, state-shape mismatch, or hard bound breach;
- solver failure: the step method could not advance a valid state.

The Lorenz example reports `finite-time divergence rate`

; it does not compute or claim a Lyapunov exponent. “Smallest” always means smallest found within the declared bounded search. Read [SCIENTIFIC_METHODS.md](/aliengineering-byte/phaseprobe/blob/main/SCIENTIFIC_METHODS.md) and [LIMITATIONS.md](/aliengineering-byte/phaseprobe/blob/main/LIMITATIONS.md).

```
python -m pip install -e ".[dev]"
python -m ruff format --check .
python -m ruff check .
python -m mypy src tests
python -m pytest --cov=phaseprobe
python -m build
python scripts/check_links.py
python scripts/hygiene.py
```

See [CONTRIBUTING.md](/aliengineering-byte/phaseprobe/blob/main/CONTRIBUTING.md) and the concrete good-first-issue templates in `.github/ISSUE_TEMPLATE/`

.

Apache-2.0. Copyright 2026 Ali. Citation metadata is in [CITATION.cff](/aliengineering-byte/phaseprobe/blob/main/CITATION.cff).
