Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 56 additions & 0 deletions docs/adr/0001-independent-implementation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# ADR-0001 — Independent implementation with a shared conformance contract

- **Status:** Accepted
- **Date:** 2026-07-11

## Context

OCPP DebugKit already exists as `@ocpp-debugkit/toolkit`: a TypeScript library,
CLI, and web app that parse OCPP traces, detect failures, and generate reports —
deliberately offline, and explicitly *not* a CSMS, simulator, or active endpoint
tester. Studio is a native desktop application that claims exactly the live,
system-level territory the toolkit declares out of scope.

The question is how the two relate. Options considered:

1. **Share the toolkit's code** — e.g. wrap the TypeScript engine in a WebView
shell, or ship it as an embedded runtime. This couples Studio to a JavaScript
runtime and to the toolkit's release cadence, and undercuts the reason to
build natively at all.
2. **Reimplement the analysis engine in Zig, sharing nothing.** Two independent
implementations that risk silently diverging in behavior.
3. **Independent implementations bound by a specification contract.** Studio
reimplements the engine in Zig but is held to the toolkit's observable
behavior through shared fixtures and golden outputs.

## Decision

Studio is a **fully independent implementation** written in Zig. It shares **no
code** with the toolkit. The two projects meet only at a **conformance
contract**:

- the trace input formats (JSON object, JSONL, bare array);
- the canonical normalized event model (`Event` / `Session` / `Failure`);
- the failure taxonomy (rule ids, severities, thresholds);
- the scenario fixtures and their expected results.

Conformance is enforced mechanically: a pinned snapshot of the shared scenario
fixtures plus golden detected-failure sets is vendored into `conformance/`, and
CI runs Studio's engine over them and asserts an exact match. The contract is
versioned (`contract-v1`); it may later graduate to its own repository if drift
pressure appears, but not before it needs to.

Where the toolkit's prose documentation and its code disagree, Studio mirrors the
**code** (the observable behavior), not the prose.

## Consequences

- Studio is free to be idiomatic Zig and to exploit native capabilities without
dragging along a JavaScript runtime or the toolkit's abstractions.
- A trace captured in Studio opens in the toolkit's inspector and vice versa —
the shared format is a real interoperability guarantee, and a marketing story:
two independent implementations, one format.
- The cost is a second implementation of the engine, and the discipline of
keeping goldens current. The conformance harness (milestone S2) is what makes
that discipline cheap and automatic.
- Behavioral divergence becomes a CI failure, not a silent bug.
44 changes: 44 additions & 0 deletions docs/adr/0002-macos-first-platforms.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# ADR-0002 — macOS-first, Linux in CI, Windows post-1.0

- **Status:** Accepted
- **Date:** 2026-07-11

## Context

Studio targets desktop. The Native SDK supports macOS, Linux, and Windows, but
not equally: macOS is the deepest and most polished surface, Linux and Windows
are exercised in CI, and some niceties (native context menus, menu-bar extras)
are macOS-only today. Studio is also, for now, built by a single maintainer.

Committing every UI decision to three release-grade platforms from day one would
triple the cost of every choice before the product has proven itself. Ignoring
the other platforms entirely would let cross-platform assumptions rot until a
painful port later.

## Decision

**macOS-first, with Linux validated in CI from day one, and Windows deferred
until after 1.0.**

- Develop and polish on macOS.
- Keep Linux building and testing in CI on every change. The pure engine and the
headless view/model tests run cross-platform (`native test -Dplatform=null`),
and a Linux Xvfb job drives the running GUI through the automation harness — so
cross-platform breakage surfaces immediately, not at port time.
- The GPU-surface GUI is macOS-first; the Linux GUI is validated headlessly in CI
and promoted toward release quality around 1.0.
- Windows is out of scope until after 1.0.

## Consequences

- Fast iteration on the primary platform, without paying a three-platform tax on
every UI decision.
- Linux can never silently rot: CI compiles and exercises the engine there
continuously, which matters most for the pure-Zig OCPP engine.
- The CI split is asymmetric by design — full build + GUI smoke on Linux (Xvfb),
build on macOS, headless tests on both. This is a deliberate consequence of
where GUI automation is cheapest to run in CI, not a statement that Linux is
the primary target.
- Windows users have no build until post-1.0. Accepted for now.
- This decision is revisited at 1.0, when Linux is promoted to a first-class
release target and Windows is reconsidered.
46 changes: 46 additions & 0 deletions docs/adr/0003-native-rendered-ui.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# ADR-0003 — Native-rendered UI, no WebView

- **Status:** Accepted
- **Date:** 2026-07-11

## Context

The Native SDK supports two UI architectures that can even coexist in one app:

1. **WebView shell** — render a web frontend (React, Next, Vite, …) inside a
platform WebView, with a bridge to native Zig. This would let Studio reuse the
toolkit's existing React inspector components.
2. **Native-rendered** — declarative `.native` markup views driven by a Zig
`Model` / `Msg` / `update` loop, drawn by the SDK's own engine. No browser, no
WebView, no web frontend.

The WebView route is the fastest path to a UI because it reuses existing web
code. But it reintroduces exactly what Studio was created to escape: a browser
engine, a JavaScript runtime, web performance ceilings, and a coupling to the
toolkit's frontend. It would make Studio a desktop wrapper around the web app
rather than a distinct native instrument.

## Decision

Studio's UI is **native-rendered**: `.native` markup views plus Zig logic on the
`UiApp` loop, drawn by the SDK engine. **No WebView, no web frontend, and no
reuse of the toolkit's React components** — consistent with the zero-code
relationship in [ADR-0001](0001-independent-implementation.md).

Views stay declarative; all side effects (subprocesses, sockets, filesystem,
clipboard) flow through the update-side effects channel, keeping the UI a pure
function of the model.

## Consequences

- Instant startup, a small binary, low memory, and no GC pauses — the native
performance that justifies a separate desktop product, and what lets Studio
handle traces far larger than a browser tab.
- The UI must be built in the SDK's markup + Zig model, not in familiar web
tech. This is a real learning and authoring cost, and it means respecting the
engine's per-view budgets (virtualized lists for large event timelines).
- No dependency on a browser engine's release cadence or security surface.
- If a genuine need for embedded web content ever appears (rendering a
third-party HTML report, say), the SDK's WebView pane can be added for that
surface specifically — without making the app WebView-based. That would be a
new ADR.
48 changes: 48 additions & 0 deletions docs/adr/0004-zig-native-sdk-zero-config.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# ADR-0004 — Zig + Native SDK on the zero-config build

- **Status:** Accepted
- **Date:** 2026-07-11

## Context

Studio needs a toolchain for a native desktop app that can open raw sockets, run
for days, render its own UI, and ship as a single binary. Two sub-decisions:

1. **Language / framework.** The native-rendered UI decision
([ADR-0003](0003-native-rendered-ui.md)) points at the Native SDK, whose
native surface is authored in Zig. Zig also fits the systems-level work Studio
needs (a WebSocket proxy, streaming parsers over gigabyte traces) with manual
memory control and no runtime.
2. **Build ownership.** The Native SDK CLI can scaffold either a *zero-config*
app (the CLI owns the build graph; no `build.zig` in the repo) or an *ejected*
app (`native eject` writes an owned `build.zig` / `build.zig.zon`). Zero-config
keeps the repo minimal but cedes build control to the CLI; ejecting grants
full control at the cost of owning framework-wiring boilerplate.

## Decision

Studio is written in **Zig on the Native SDK**, and stays on the **zero-config
build** until a concrete need forces ejection.

- `app.zon` is the manifest; `src/` holds the app; the `native` CLI (`dev`,
`test`, `build`, `check`, `doctor`, `package`) owns the build.
- The framework is provided by the pinned `@native-sdk/cli` package, so CI needs
only Node, Zig, and `npm install -g @native-sdk/cli` — no framework checkout or
vendoring.
- The OCPP engine is organized so it stays pure Zig and headlessly testable,
independent of the UI and platform layers, behind a version-tagged protocol
boundary so OCPP 2.0.1 can be added without reworking 1.6J.

## Consequences

- A minimal repository: no build files to maintain, and upgrades come by bumping
one pinned CLI version.
- The trade-off is less build control. Custom build steps (extra link inputs, a
vendored C dependency such as a TLS library for the future secure proxy) are
not expressible until the app ejects. When that need is real — most likely
around live-capture TLS — Studio will `native eject` and own its `build.zig` in
a dedicated ADR-superseding change.
- Pinning the CLI version keeps a pre-1.0 SDK's churn from breaking `main`
unexpectedly; CI catches breakage on upgrade.
- Zig is itself pre-1.0. The toolchain is pinned to `0.16.0` and upgraded
deliberately.
16 changes: 16 additions & 0 deletions docs/adr/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Architecture Decision Records

This directory records the significant architecture decisions for OCPP DebugKit
Studio. Each ADR captures one decision in a consistent form —
**Status → Context → Decision → Consequences** — so the reasoning behind the
project's shape stays legible over time.

ADRs are immutable once accepted: to change a decision, add a new ADR that
supersedes the old one rather than editing history.

| ADR | Title | Status |
| --- | --- | --- |
| [0001](0001-independent-implementation.md) | Independent implementation with a shared conformance contract | Accepted |
| [0002](0002-macos-first-platforms.md) | macOS-first, Linux in CI, Windows post-1.0 | Accepted |
| [0003](0003-native-rendered-ui.md) | Native-rendered UI, no WebView | Accepted |
| [0004](0004-zig-native-sdk-zero-config.md) | Zig + Native SDK on the zero-config build | Accepted |
Loading