35e593ab63
Two independent wiki updates bundled (all docs):
1. dingtian-dt008-reader.md: phantom optical decodes on the park-buzi EXIT
reader (empty pre-opening site, low-sun afternoons). Chain of evidence:
READ log lines carry the reader's own serial (H05MA5B0) → physical device,
not a network source; snapshot shows nobody present; code shapes are the
giveaway (6-digit numerics = checksum-less Interleaved 2-of-5, lone "C" =
Code39/Codabar artifact) → 1D engine decoding sun-made stripe patterns
(striped arm, fence shadows, glare). No fraud exposure (11-digit Luhn ids
can't match); noise only. Fix on the entity page: vendor-tool symbology cut
to QR+Code128 + min decode length, BOTH readers; config lives ON the device
→ re-apply after any factory reset/swap. Deliberately NOT filtering
impossible codes server-side — probe recording is the anomaly path's job.
2. Backfilled two shipped-but-undocumented features (six code files already
linked the first page as if it existed):
- concepts/entry-presence-bypass.md — admin drops a FAULTY presence signal
(granular radar/camera by decision, not a master switch); every flip is a
signed config_change; persists till off; tickets stamped presenceBypassed;
radar-bypass cooldown tradeoff; "the admin is not the adversary, but
trusted never means invisible".
- concepts/setup-relay-test.md — admin-only commissioning pulse, signed
barrier_open_command BEFORE the fire so a test open never reads as the
out-of-band-open fraud signal; saved controllers/declared relays only;
radarAlert lamps excluded; pulseOpen only.
Cross-linked from operator-issued-entry.md, cataloged in index.md, logged.
Claude-Session: https://claude.ai/code/session_01Xcm6ikLgGoCxxHrxtjkk5V
2.5 KiB
2.5 KiB
type, tags, sources, updated, status
| type | tags | sources | updated | status | |||||
|---|---|---|---|---|---|---|---|---|---|
| concept |
|
2026-07-04 | settled |
Setup relay test (signed, admin-only barrier pulse)
Commissioning a lane needs a way to prove wiring: does relay N on this controller actually lift this barrier? Before this feature (built 2026-07-01) the only way was to fake a credential or short an input — both of which pollute the flows they exercise. Now the Setup controller section offers a per-relay Test button that pulses the relay directly.
The design constraint: a test open must be SIGNED
The core anti-fraud rule (append-only-event-chain) is that a physical barrier open with no
matching signed command is THE fraud signal. An unsigned test pulse would therefore read as
fraud in any reconciliation of controller logs vs. ledger. So the test signs a
barrier_open_command BEFORE the pulse fires — same ordering invariant as every real open:
source: "manual"(a deliberate human action, same as an operator barrier open),identity: relay-test:<controllerId>:<relay>,- payload:
reasonPayload("setup.relayTest", { operator, relay, controller })+relayTest: trueso reconciliation and the feed can tell a test from an intervention. - No
EventLogavailable (boot ordering) → the endpoint refuses (503) rather than fire unsigned.
Guardrails
- Admin-only (
site:update) + CSRF — the operator (the threat-model adversary) cannot pulse barriers from Setup. - Saved controllers only, and only relays the saved config declares (unknown relay → 400, unknown controller → 404, nothing signed on any refusal). No free-form "pulse anything" seam.
radarAlert(lamp) relays are excluded in the UI — they are aux outputs, not barriers (button-light-indicator); the test drivespulseOpenonly, so barrier-not-a-door holds (intent-only; the barrier firmware owns the close).- UI confirms before firing (
Test→ confirm dialog → pulse), per-relay buttons in the controller assignment row.
As-built
- Endpoint
POST /api/setup/test-relay(routes/setup.ts) — validates, signs, thenregistry.create(...)→pulseOpen(relay). Feature-detectspulseOpenon the built device. - UI:
RelayTesterinSetupWizard.tsx(access category only). Reason codesetup.relayTestin@parking/shared+ both web catalogs (i18n). - Tests:
setup-relay-test.test.ts— RBAC 403, CSRF 403, signed command on success, 400/404 refusals sign nothing, bad relay value.