Deterministic Simulation and Replay
The sim command family runs an EVSE and an EVCC as twins inside one process, without sockets, and produces a symbolic transcript of the message sequence with a SHA-256 hash. The same scenario with the same seed always yields the same transcript, so a simulation report can be replayed and verified months later, on another machine, or in CI. Use it for regression checks, for reproducing a reported sequence without hardware and for attaching a compact reproducer to a support case.
Deterministic simulations are symbolic: they record message families and state transitions, not wire bytes. They prove that ChargeLink's own sequencing is stable; they do not prove interoperability with a physical peer.
$CL = 'C:\ChargeLink\0.5.0-rc2\pc1\bin\chargelink.exe'
$Data = 'C:\ChargeLinkData'
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim policy
Catalogs
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim iso20-catalog
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim legacy-catalog
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim tls-catalog
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim iso20-negative-corpus
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim legacy-negative-corpus
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim tls-negative-corpus
ISO 15118-20 scenarios (10)
| Scenario | Category | Expected verdict | Message families |
|---|---|---|---|
common-eim-nominal | common | pass | sdp, app-protocol, session, authorization, service-discovery |
common-pnc-tls | common-security | pass | tls, app-protocol, authorization, service-selection |
dc-bpt-nominal | dc | pass | sdp, session, schedule, dc-precharge, dc-loop, stop |
dc-stop-energy-transfer | dc | pass | session, power-delivery, stop |
dc-service-renegotiation | dc | pass | service-discovery, service-selection, schedule, dc-loop |
dc-session-resume | recovery | pass | session, resume, authorization, dc-loop |
dc-timeout-recovery | fault | expected fault path | timeout, retry, safe-stop |
dc-negative-response-code | fault | expected fault path | response-code, service-selection, safe-stop |
dc-power-limit-fault | fault | expected fault path | precharge, power-limit, safe-stop |
dc-evcc-abort | fault | expected fault path | abort, safe-stop |
ISO 15118-2 and DIN 70121 scenarios (12)
iso2-dc-pnc-nominal, iso2-dc-eim-nominal, iso2-ac-eim-nominal, iso2-cert-install, iso2-cert-update, iso2-current-demand-loop, iso2-timeout-recovery, iso2-negative-payment, din-dc-basic, din-current-demand-loop, din-timeout-recovery, din-evcc-abort.
TLS/PKI/PnC campaigns (12)
iso20-pnc-contract-valid, iso20-pnc-expired-contract, iso20-pnc-untrusted-root, iso20-pnc-wrong-eku, iso20-pnc-revoked-contract, iso20-pnc-malformed-cert, iso20-pnc-ocsp-soft-fail, iso20-pnc-redaction-boundary, iso2-pnc-contract-install, iso2-pnc-contract-update, tls-hostname-mismatch, tls-private-key-export-block. All use redacted hash fixture material only.
Run one scenario
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim paired --protocol iso15118-20 --scenario dc-bpt-nominal --seed 42 --run-id sim-dc-bpt-42 --write-artifacts --output "$Data\tests\sim-dc-bpt-42.json"
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim iso20-scenario --scenario dc-timeout-recovery --seed 7 --run-id sim-timeout-7 --write-artifacts
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim legacy-scenario --protocol din70121 --scenario din-dc-basic --seed 1 --run-id sim-din-1 --write-artifacts
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim tls-campaign --campaign iso20-pnc-expired-contract --seed 1 --run-id sim-tls-expired --write-artifacts
Artifacts (under the run directory): sim\paired-simulation-report.json and sim\paired-simulation-transcript.json for paired; sim\iso15118-20-scenario-report.json / -transcript.json; sim\legacy-hlc-scenario-report.json / -transcript.json; pki\tls-pki-pnc-campaign-report.json / -transcript.json. The report contains the seed, the event count and the transcript SHA-256.
Run a suite
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim iso20-suite --profile dc-bpt-expanded --seed 1 --run-id suite-iso20 --write-artifacts
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim legacy-suite --profile legacy-expanded --seed 1 --run-id suite-legacy --write-artifacts
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim tls-suite --profile tls-pki-pnc-expanded --seed 1 --run-id suite-tls --write-artifacts
A suite runs every scenario or campaign of its catalog with the given seed and records one transcript hash per scenario. Keep the suite output of a release as the baseline; a changed hash for the same seed after an upgrade is a behavioural change that must be explained.
Replay and verify
chargelink --runtime-root "$Data\runtime" --artifact-root "$Data\artifacts" --json sim replay --trace "$Data\tests\sim-dc-bpt-42.json" --output "$Data\tests\sim-dc-bpt-42.replay.json"
Expected: status: replay_verified, expected_transcript_sha256 equal to actual_transcript_sha256, mismatch: null. A mismatch names the first divergent event. Replay accepts the simulation report written by --output, not a live protocol trace.
Practical uses
- Reproduce a software regression without reconnecting laboratory hardware.
- Compare behaviour before and after a ChargeLink update (same seed, compare hashes).
- Verify a known negative case in CI (
expected_verdict: expected_fault_path). - Attach a deterministic reproducer to a support ticket (the report file is self-contained).
- Review a test sequence when the original bench is unavailable.
Related engineering lanes
The EXI corpus (exi roundtrip, exi completeness, exi negative-corpus) exercises the native codec against golden bytes.

