--- type: decision tags: [parking, decisions] sources: [parking-system-architecture] updated: 2026-06-21 status: settled --- # Standing Decisions (settled) The decisions treated as settled in the design notes. (See [[parking-system-architecture]] "Summary of standing decisions".) - **Stack:** [[turborepo]] · [[fastify]] (Node) · [[react-vite-spa]] · [[sqlite]] + [[drizzle-orm]] · [[local-jwt-auth]]. All MIT/Apache/BSD — **no vendor lock, no rug-pull risk** (see [[payload-cms]]). Full table in [[technology-stack]]. - **Scoped exception (2026-06-15):** the [[opencv-anpr-service]] — a **separate local process**, not linked into the app — **may use AGPL** components (plate/vehicle models). The exception is bounded to that process; the Node/React app stays strictly MIT/Apache/BSD. See [[vision-service]]. - **Platform:** a **dedicated, hardened Linux appliance** (LUKS + GRUB password + Secure Boot), **not Windows/WSL** — see [[disk-os-hardening]]. - **Desktop shell:** the operator UI ships as a **[[desktop-shell-tauri|Tauri v2]]** kiosk wrapper (chosen over Electron, 2026-06-21) — small footprint, no bundled Chromium to patch, and a deny-by-default native surface that fits [[threat-model|the booth-operator threat model]]. The shell stays **thin**: all privileged logic remains in [[fastify]]. One open dependency — the appliance's WebKitGTK version (see [[open-questions]] #11). Ships as a **`.deb`** (the AppImage bundles a runner's WebKitGTK and fails on the 26.04 booth — 2026-09-04); its backend address is **operator-entered at runtime**, not baked in; and **in-app updates are an admin-only action** behind the polkit password prompt (user, 2026-09-04) — never make that prompt passwordless. - **Integrity:** append-only, hash-chained, **software-signed** event log ([[append-only-event-chain]]) — hardware-backed signing (a non-extractable key in the **[[tpm|TPM]]** or a **USB HSM**; the [[atecc608]] is [[open-questions|upcoming, not present]]) is the target that makes it unforgeable by a host owner ([[hardware-signer-options]]). **[[reconciliation]] is the anti-fraud control**; encryption protects only at-rest (see [[threat-model]]). - **Access control:** the **[[dingtian-relay]]** relay+input controller, on an **isolated VLAN** ([[network-isolation]]). Chosen because its **inputs are decoupled from its relays**, enabling host-in-the-loop ticket-first entry — the resolution to [[access-controller-button-flow]]. (The [[uhppote-controller]] and [[zkteco-controller]] were evaluated and **rejected** — kept as historical record. The [[esp32-custom-controller]] remains the documented prevention-grade alternative — the [[trust-boundary]] fork.) - **Readers:** prefer [[wiegand]]-into-controller for permit holders (autonomous); host-in-the-loop for [[lpr-camera|LPR]]/QR/pure-network readers; both can share a relay (see [[entry-exit-readers]]). Unsettled items live in [[open-questions]].