How we verify.
What we test, how, and what the last run said.
The product's code and its test runs live in private repositories, so the logs can't be linked here — every run named below can be opened in front of your reviewer, in a demo.
Installed from scratch, network sealed.
On every change to the product, the release bundle is built and installed in production mode on a fresh Linux machine — with a firewall rule blocking every outbound connection from the containers. Then the checks below run against it, and then the full API test suite runs through the reverse proxy. A release can't be published unless this passed on that exact commit.
Release 1.5.2: Unit tests — 1,844 passed, 0 failed; Production install from the release bundle — 70 passed, 0 failed (run 40347574837); End-to-end checks through nginx — 5,965 passed, 0 failed (run 40347574837).
- The site comes up through the reverse proxy over TLS, and plain HTTP redirects to HTTPS.
- TLS 1.1 is refused; 1.2 and 1.3 are accepted.
- The app’s content security policy allows only the installation itself.
- The company administrator signs in with the one-time password the installer printed.
- Sign-in records carry the client’s address, not the proxy’s.
- Live updates upgrade to WebSocket through the proxy, and a 20 MB upload passes it.
- Metrics need their token, and the metrics and alert rules pass Prometheus’s own checks.
- Logs are JSON, one object per line.
- A container cannot reach the internet — the firewall rule holds for the whole run.
- The command-line status and verification checks pass.
- The installer’s own backup-and-restore test passes; an uploaded file survives recreating the app container.
- A live restore brings back a dropped table and the uploaded file.
- The readiness check reports the database when it stops, and recovers when it returns.
Upgraded in place, nothing lost.
On the product's own test machine, the previous release is installed, given devices and data, then upgraded the way the install guide says — and everything registered and stored must still be there.
Recorded run: 2026-10-15, commit 4688c06, “Connect upgrade” run 38705628544 — passed. Log shown on request (private repository).
- The previous release is installed with the bundled tracker server and LoRaWAN network server, and a tracker, a gateway and a sensor are registered, their data arriving.
- The upgrade follows the install guide: a backup first, then the new bundle’s checksum checked.
- After the upgrade the new versions run healthy on the same volumes, and every registration and stored reading survived.
- New data flows through the upgraded servers; the command-line status is ready and the verification passes.
Sign-in through a real identity provider.
Not a mock: the test starts Keycloak, configures it the way a customer's IT team would, and signs in through Keycloak's own login form.
Recorded run: 2026-09-30, commit c7f4d64, “SSO (Keycloak)” run 36748242834 — 16 of 16 checks passed against Keycloak 26.0.8 (the backend records a later green run, on 35955e1, without its id or log). Log shown on request (private repository).
- A real Keycloak is started and configured: a realm, a confidential client with PKCE (S256), a group and a user.
- HOLOIN saves it as the identity provider and its connection test reads Keycloak’s discovery document and keys.
- An email address on the company’s domain is routed to Keycloak.
- The user signs in through Keycloak’s own login form (authorization code with PKCE).
- On first sign-in the user is created with the role their Keycloak group maps to.
- The session refreshes through Keycloak’s refresh token, with a freshly verified ID token.
- A forged state is refused.
- When Keycloak rotates its signing key, the next sign-in still verifies (the key set is refetched once).
- Removed from the group in Keycloak, the user’s next refresh is refused and the account is deactivated; added back, the next sign-in reactivates it.
- A wrong client secret is refused by Keycloak at the code exchange.
- Every attempt is recorded in the sign-in log.
Every push, every module.
Release 1.5.2: unit tests — 1,844 passed, 0 failed.
- Type checks and syntax checks across the code.
- The hardware catalog validates against its schema.
- The public facts this website shows are regenerated from the code and must match — a stale claim fails the build.
- The tester’s guide must list every acceptance item and every user-facing message.
The homepage, replayed.
Each scene on our homepage is something that happened in a run of these scenarios on a demo installation, on 2026-10-01 (commit 72c5da6) — the times and names are that run's. The same simulators ship with the product, so a demo replays them on your screen.
- Dispatch trip — 12 passed, 0 failed.
- Farm irrigation — 7 passed, 0 failed.
- Building operations — 12 passed, 0 failed.
Held to the same rule.
- Every build fails if a page loads anything from another server — font, script, image or style.
- Pages ship no JavaScript.
- Every “live”, “beta” and “in development” label is generated from the product’s own facts file, not typed by hand.
- Every page scores at least 95 in each Lighthouse category, or the site doesn’t deploy.
What proved each item.
Each item on What's inside, with the acceptance run that proved it, what in the product shows it, the release it is included in, or its sealed run pending — and what is still in development.
- LoRaWAN (how readings arrive) — acceptance run 36943905354 (2026-10-02)
- CoAP (how readings arrive) — included in release 1.5.2
- HTTP (how readings arrive) — acceptance run 36994982003 (2026-10-02)
- Monitoring-tool alerts (how readings arrive) — acceptance run 39179177486 (2026-10-19)
- LwM2M (how readings arrive) — included in release 1.5.2
- MQTT (how readings arrive) — acceptance run 36994982003 (2026-10-02)
- OCPP 1.6 · 2.0.1 (how readings arrive) — included in release 1.5.2
- Sparkplug B (how readings arrive) — included in release 1.5.2
- Cellular trackers (how readings arrive) — acceptance run 36943905354 (2026-10-02)
- BACnet (how readings arrive) — acceptance run 37058180386 (2026-10-02)
- Modbus TCP (how readings arrive) — acceptance run 37058180386 (2026-10-02)
- OPC UA (how readings arrive) — acceptance run 37058180386 (2026-10-02)
- KNX (how readings arrive) — beta — acceptance run 37058180386 (2026-10-02)
- SNMP (how readings arrive) — acceptance run 39179177486 (2026-10-19)
- SunSpec (how readings arrive) — acceptance run 38852071304 (2026-10-16)
- Vehicles (the twin) — included in release 1.5.2
- Farms, fields, zones (the twin) — included in release 1.5.2
- Buildings, floors, rooms (the twin) — included in release 1.5.2
- Remote sites (the twin) — acceptance run 38852071304 (2026-10-16)
- Energy plants (the twin) — acceptance run 38852071304 (2026-10-16)
- Charging depots (the twin) — acceptance run 38852071304 (2026-10-16)
- The IT room’s equipment (the twin) — included in release 1.5.2
- What powers and connects what (the twin) — included in release 1.5.2
- The path to every device, and the first broken hop when one goes quiet (the twin) — included in release 1.5.2
- The BMS, mapped in — verified against a simulated BMS (the twin) — included in release 1.5.2
- Live over a socket, history on demand (the twin) — shown by src/realtime/realtime.gateway.ts; the devices’ and homes’ history endpoints
- Dependencies, upstream cause, blast radius (the twin) — shown by the IT room’s connections
- Thresholds, schedules, events, time windows (rules and actions) — shown by src/rules/ (reading, schedule and event triggers; the time-window condition)
- Alarms with escalation, quiet hours (rules and actions) — shown by src/alarms/alarms.service.ts (escalation tiers); the rule’s quiet hours (src/notifications/)
- Work orders (rules and actions) — shown by the building acceptance run: the alarm becomes a work order on the technician’s phone
- Commands completed only on evidence (rules and actions) — shown by a command completes on the device’s report, not on send (CLAIMS.md S3)
- Usual for this hour of the week (what it learns) — included in release 1.5.2
- How much the twin knows, shown (what it learns) — included in release 1.5.2
- Dependencies it noticed, for you to confirm (what it learns) — included in release 1.5.2
- Lifetime: observed from wear, counted from duty, rated where a maker’s datasheet gives it — each labelled apart (what it learns) — included in release 1.5.2
- “What if this fails” scenarios (what it learns) — included in release 1.5.2
- Rules proposed from your own failures, backtested (what it learns) — included in release 1.5.2
- Trends, and when a line is reached (what it learns) — shown by the twin memory’s normal
- One install bundle, no internet needed (running it) — shown by the Compose acceptance run: installed with its internet cut
- Backups, restore, monthly drill (running it) — shown by the Compose acceptance run: a backup restored, a dropped table recovered
- Two-step sign-in · single sign-on (running it) — shown by src/auth/ (password and TOTP); the SSO run against an identity provider
- Support access with consent, every action logged (running it) — shown by src/support/ (granted by your administrator, for a set time; CLAIMS.md S2)
What these tests don't prove.
- The tracker integrations are tested with simulated trackers sending in Traccar’s format, not yet with physical devices.
- The phone app is tested in a phone-sized browser, not yet on physical phones.
- The catalog’s starting thresholds are marked unverified until checked against each device’s documentation.