--- type: decision tags: [parking, decisions, open] sources: [parking-system-architecture] updated: 2026-06-29 status: open --- # Open Questions / Next Steps **Not yet decided** (or decided-but-not-yet-built), and they drive everything else — settle before procurement. (See [[parking-system-architecture]] §10.) 1. **Lane topology.** One host per lane, or one central host driving networked devices in each lane? Decides how many controllers, printers, UPSs, and [[sqlite]] instances exist, and the failure blast radius. (A single central host is a single point of failure for *all* lanes.) 2. **Failure modes.** Define per direction what happens to barriers on host/power/network loss — particularly **fail-open on exit** for egress safety. Currently unaddressed. See [[fail-state-safety]]. 3. **Payment subsystem.** Manned booth (P2PE terminal + cash drawer) vs unmanned pay station; confirm **PCI scope is kept out of the application** via a standalone certified terminal (see [[bom]]). 4. **Reconciliation channel.** Even if "offline," establish *some* periodic path (USB, hotspot, manager visit) to reconcile the signed log against an external authority — the real anti-fraud control. See [[reconciliation]]. 5. **Durability / backup.** _(Design SETTLED + first slice BUILT 2026-06-29 — see [[backup-recovery]]; engine + local/mounted target + daily timer + manual route done, SFTP/UI/restore-tooling pending.)_ A disk failure / stolen-or-destroyed PC currently leaves **total revenue-history loss**. Settled design: an **admin-driven encrypted full-DB backup** (online-backup/`VACUUM INTO`, snapshots included) to a **local/USB · SMB/NFS · SFTP** target, **manual button + in-process daily timer**, **keep-last-N + dailies** retention, encrypted with a **dedicated `park_buzi_backup_key`** (separate Komodo secret, *not* the signing key). Recovery = backup file **+** the two escrowed keys held out-of-band; a restored copy must still `verifyChain`. **Key-custody stance:** `EVENT_SIGNING_KEY` stays **decoupled from the TPM** (an extractable, escrowed software key) precisely so it survives total hardware loss — the conscious trade against #6 (a TPM-sealed signing key would be unforgeable but **unverifiable after the machine dies**). **Restore is admin-only/out-of-band** (operator-adversary surface — [[threat-model]]). See [[backup-recovery]], [[fleet-deployment-komodo]], [[disk-os-hardening]], [[reconciliation]] (#4). 6. **Secure-element integration.** Confirm [[atecc608]] wiring/usage on the host (event signing). The [[esp32-custom-controller]] command-authentication use is **deferred — not being implemented for now** (access control is the [[dingtian-relay]] behind [[network-isolation]]); revisit only if prevention-grade device auth becomes a requirement. 7. **JWT signing: symmetric vs. asymmetric key.** _(Raised by the commit security review, not the source doc.)_ Auth currently uses a symmetric HMAC secret (`@fastify/jwt`, see [[local-jwt-auth]]) — the same secret signs *and* verifies, so it must live on every host that validates tokens. Consider rotating to an **asymmetric key (RS256 / EdDSA)** so the server holds only the **public key** to verify; the private signing key can then live in the [[atecc608]] or a key-management step. This mirrors the "store only the public key" property already used for [[atecc608]] event signing and the [[challenge-response-auth]] scheme — compromising a verifying host yields nothing that can forge a token. Decide before multi-host / multi-lane deployment (see #1 lane topology), since that's when shared-secret distribution becomes the liability. 8. **Exchange-rate (FX) system.** _(Raised by the [[tariff]] design, 2026-06-15.)_ Currency is selectable per tariff version and the money model is FX-ready (`payment` stores currency + a reserved `fxRate`), but **no conversion is built**. If multi-currency pricing/charging is ever needed, it requires an **offline** rate source (rates can't depend on the network — [[offline-first]]), a base currency, and a rounding policy. Deferred; nothing blocks adding it later without migrating stored amounts. 9. **Pay-station money corners — receipts & refunds/change.** _(Raised by the scope sweep, 2026-06-15; deferred until pay-station hardware is chosen.)_ Not yet designed: **receipts / VAT invoices** (fiscal receipt with tax number + sequential numbering may be legally required — could change what the `payment` event must store) and **refunds / overpayment / change** (cash change, "exact change only", a refund as a signed reversal event). Both depend on the unmanned-vs-manned payment subsystem (#3) and the note/coin/card acceptor hardware. Revisit at procurement. 10. **Snapshot retention.** _(Raised by the [[entry-exit-points]] camera-snapshot build, 2026-06-16.)_ Entry/exit snapshots are stored as BLOBs in the [[sqlite]] `snapshots` table. This grows the single DB file fast (~100–300 KB per image × every entry **and** exit), and SQLite doesn't reclaim deleted-blob pages without `VACUUM`. **Undecided:** pruning policy (age-based vs. total-size cap), VACUUM cadence, and how this interacts with the #5 backup strategy (blobs bloat every backup). Until decided, snapshots accumulate unbounded. See [[entry-exit-points]]. _(Update 2026-06-29: pruning is now disk-pressure based — see [[entry-exit-points]]; and the settled #5 backup includes snapshot BLOBs by default, with a noted future "exclude snapshots" toggle since they dominate backup size — see [[backup-recovery]].)_ 11. **Appliance OS image → WebKitGTK version (Tauri dependency).** _(Raised by [[desktop-shell-tauri]], 2026-06-21; narrowed same day.)_ The chosen [[desktop-shell-tauri|Tauri v2 desktop shell]] renders through the **host's WebKitGTK**, not a bundled browser. The risk reduces to which OS the appliance runs: - **Best case — Ubuntu 26.04 LTS desktop (intended):** ships a current, distro-maintained WebKitGTK → this question is **effectively resolved**; just confirm the built SPA renders on the actual image and pin it. - **Worst case — Windows 11 + WSL + Docker:** this **conflicts with the standing platform decision** (Linux appliance, *not* Windows/WSL — see [[standing-decisions]], [[disk-os-hardening]]) and a GUI shell doesn't live inside headless WSL/Docker. Fallback is **no native shell — a kiosk browser** at the local [[fastify]]-served SPA (Electron only if a standalone Windows installer is mandated). See [[desktop-shell-tauri]] for the decision table. Close this once the appliance OS image is fixed and the SPA is verified against its WebView. (Ties to #1 lane topology / image standardization.) 12. **TPM 2.0 hardening — implementation (to build).** _(Recorded 2026-06-21; analysis in [[tpm]].)_ On the Ubuntu 26.04 LTS appliance, harden using the host **TPM**: (a) **sealed-LUKS auto-unlock** (`systemd-cryptenroll --tpm2-device`) so the encrypted disk auto-unlocks only on an untampered boot → unattended reboot after power loss; (b) optionally hold the **non-extractable host event-signing key** in the TPM (a new `Signer` impl — no `EventLog` change; mirrors the [[atecc608]] swap), defeating the offline pull-the-disk-and-re-sign attack. **Must include:** require **TPM 2.0** (reject 1.2), **prefer fTPM** + a per-op **PIN/auth policy** (not PCR-only — bus-sniff), a **LUKS recovery passphrase**, and a **re-seal-on-update runbook** (kernel/GRUB/BIOS updates change the PCRs and lock the disk). TPM **complements, never replaces**, [[reconciliation]]; it does nothing against a rooted live host or the operator. Moot in the Windows + WSL fallback. See [[tpm]], [[disk-os-hardening]]; relates to #6 (host secure-element by platform) and #13. 13. **Startup chain-integrity self-check (to build).** _(Raised by the pull-the-disk trace, 2026-06-21.)_ `verifyChain()` exists and pinpoints any tamper, but **nothing invokes it on boot** — a tampered DB loads and serves normally (detectable but undetected). Wire a **startup self-check** that runs `verifyChain()` and, on a break, **flags degraded state / writes a signed `anomaly` + alarms** (surfaced to the booth footer / next reconciliation). Open: refuse-to-serve vs. serve-degraded — lean **serve-degraded + loud alarm** (fail-open on exit still governs; refusing to boot could strand a lane). Software-only, independent of the TPM/[[atecc608]] hardware. See [[append-only-event-chain]]. 14. **Printer USB transport — confirm the on-site printer + bake the provisioning.** _(Recorded 2026-06-24; the transport code is built — see [[printer-usb-transport]].)_ The ESC/POS drivers now drive **TCP (port 9100) OR local USB (`/dev/usb/lp0`)** behind one render layer, selectable per device. **Open:** is the actual booth printer USB or network? (The site's verified units are *networked* — Cashino `10.0.10.9`, Rongta `10.0.10.10` — so USB may be unused here; the original BOM listed "Epson TM / Citizen (USB **or** network)", so a future site may need it.) If USB is used, the **appliance image** must (a) load/keep the **`usblp`** kernel module bound to the printer (CUPS can claim the interface first), and (b) ship a **udev rule** giving the non-root server process write access to `/dev/usb/lp*`. Both are [[appliance-provisioning]] steps, **not app code**, and are **unverified on hardware**. Close this once the printer transport per site is fixed and (if USB) the udev/usblp rule is in the image and a real USB print is verified. Relates to #1 (lane topology / image standardization). See [[printer-usb-transport]], [[rongta-printer]].