Studio and the TypeScript toolkit are independent implementations of the same OCPP analysis behavior (ADR-0001). This directory is the machine-checked contract between them: the shared scenarios and the failure codes each must detect.
fixtures/<name>.json— the 18 shared scenario traces (the input).goldens/<name>.json— each scenario's expected de-duplicated, sortedFailureCodeset (the output to match), as a JSON array of wire codes.harness.zig— runs, undernative test, the full engine (parseTrace → buildSessionTimeline → detectFailures) over every fixture and asserts its detected code set equals the golden — the same comparison the toolkit'sevaluateScenariomakes. A missing or extra code fails the scenario by name.
Both the fixtures and the goldens are exported from the toolkit — the source of
truth — so a golden can never drift from what the reference implementation
actually detects. They are regenerated (not edited by hand) from the toolkit's
scenarios and evaluateScenario:
// run against a built @ocpp-debugkit/toolkit
import { scenarios } from '@ocpp-debugkit/toolkit/scenarios';
import { evaluateScenario } from '@ocpp-debugkit/toolkit';
for (const s of scenarios) {
const detected = [...new Set(evaluateScenario(s).failures.map((f) => f.code))].sort();
// fixtures/<s.name>.json <- JSON.stringify(s.trace)
// goldens/<s.name>.json <- JSON.stringify(detected)
}The Native SDK zero-config build (ADR-0004) embeds test data with @embedFile,
which resolves within the source module root. Keeping the vendored contract here
lets the harness embed it directly — no runtime file I/O, fully hermetic.
Tagged contract-v2 (OCPP 1.6J), 18 scenarios, regenerated against toolkit
0.4.5. When the contract changes — new rules, new scenarios, or OCPP 2.0.1 —
regenerate against the matching toolkit release and bump the tag. Earlier versions
stay reachable through the release tags rather than being kept side by side here:
v0.5.4's tree carries contract-v1 (15 scenarios).
Regenerating is expected to reproduce the existing files byte for byte, and that
is worth checking when you do it: if a fixture you did not mean to touch changes,
either the toolkit version is wrong or the change is bigger than you thought.
contract-v2 was cut that way, so it is a strict superset of v1.
See ADR-0013 for the v2 cut and docs/CONTRACT.md for the public contract.