Repository navigation
test(contract): pin the shipped AP SSID format - #489
felixfelix-bot wants to merge 2 commits into
Conversation
The open AP is named `<brand>-<4 hex characters>` (`TollGate-A1B2` for the
default brand) and both radios carry that one name. Nothing enforced it: the
4-character device suffix and the single-name property were conventions in
99-tollgate-setup, so a band suffix ("TollGate-A1B2-2.4GHz") or a hardcoded
brand could come back unnoticed. The Go side keys on the `TollGate-` prefix
(discovery_log.go `hasTollGateSSID`, vendor_element_manager.go
`calculateScore`), and the SSID rides in every beacon, so the drift is both a
client-matching and a naming-honesty bug.
tests/contract/check-ssid-format.sh asserts the contract in two layers:
- behavioural: sources the real load_brand()/setup_public_wifi() out of the
script (driver stripped) and runs them against a stub `uci` that records
what they would have written, then checks the SSID actually generated —
both radios matching ^TollGate-[0-9A-F]{4}$ for the default brand, one
shared name for both radios, a per-device 4-hex suffix over 6 generations.
- structural: checks the assignment sites a checkout cannot execute — the
same-version reinstall path recovers its SSID from live config and the
whitelabel branch reads /etc/tollgate/brand — failing on a band token or on
an SSID written from anything but a variable.
Red evidence, all reverted before this commit: appending "-2.4GHz" to the
gateway name fails 12 checks; hardcoding the brand at the `.ssid` write fails
the structural layer (which the behavioural layer alone cannot see); deleting
the write fails the anti-vacuity guard.
Wired into both CI test workflows (build-purity job), hooks/pre-commit, and
the release/contribution runbooks.
Refs: t_9e5f0b8d
Public AP is BRAND-XXXX with a 4-hex uppercase suffix from /dev/urandom, shared across the 2.4GHz and 5GHz radios (band steering). Private management AP is BRAND-Private-XXXX with a WPA2 word-word-word-NN passphrase. nodogsplash gatewayname derives as '<gateway> Portal'. The public format is pinned by tests/contract/check-ssid-format.sh. Documents the post-fix private SSID (TollGate-Private-XXXX); the operator-username variant (c08r4d0r-XXXX) is a security leak being fixed on pr/private-ssid-no-operator-username.
Verification — the pin bites on all four injected drifts; wired into both CI lanes + pre-commit; composes with #487 in both merge ordersIndependently verified at head Where the checker lives and when it runs.
Green/Red evidence.
Also green at the head: Coverage of every derivation path. A tree-wide grep shows the only Is the pattern the minimal invariant? Close to it. What's pinned is exactly the three load-bearing properties: brand prefix from the brand selector (Go-side prefix matching in Compatibility with #487 — verified in this direction too. The #487-thread verification already ran this checker green against #487's tree; I reproduced it independently: fetched #487 head Smaller notes. CHANGELOG entry present under Disposition: land. The contract is real (four independent red proofs), the wiring is triple-confirmed and idempotent for already-passing trees, coverage matches every SSID derivation path in the repo, and it composes with #487 in either merge order. Optional follow-ups, none blocking: (1) derive the expected brand prefix from the sourced |
|
Technical review (evidence-gathering pass, not an approval). What it does. Promotes the open-AP SSID format to a checked contract: Verification on this head ( Sequencing: same note as #487 — the two PRs add adjacent steps in both Disposition: land — after #487, with the one-round rebase. |
|
Rebase needed against current |
|
Superseded by a rebased replacement: main moved (band-aware radio setup, #491's epoch token-emit) and the original head branch was deleted server-side. The replacement carries the same contract + a harness adapted to the band-aware setup (detect_band_radios bootstrap, tollgate_*_open readback), mutation-verified. |
What
tests/contract/check-ssid-format.shpins the open AP's SSID to<brand>-<4 hex characters>—^TollGate-[0-9A-F]{4}$for the default brand — with both radios broadcasting that same one name. It runs as a CI gate in thebuild-purityjob (both.github/workflows/test.ymland.ngit/act/workflows/test.yml) and is wired intohooks/pre-commitnext to the other shipped-default checks.The SSID is product surface: it is in every beacon, the operator reads the 4-character suffix to tell two routers apart, and the module keys on the
TollGate-prefix (src/wireless_gateway_manager/discovery_log.go→hasTollGateSSID,vendor_element_manager.go→calculateScore). The exact shape was only a convention in99-tollgate-setup, so a band suffix (TollGate-A1B2-2.4GHz) or a hardcoded brand could come back unnoticed.How it checks
Behavioural layer. It sources the real
load_brand()/setup_public_wifi()out of99-tollgate-setup(the driver is stripped, since that part reads and writes/etc,/procand the setup flag) and runs them against a stubucithat records every write. The assertions are on the SSID the script actually generated, not on its source text:^TollGate-[0-9A-F]{4}$on the default brand;[0-9A-F].Structural layer. The assignment sites a checkout cannot execute: the same-version reinstall path recovers its SSID from live config (and re-asserts it after the uhttpd repair), and the whitelabel branch reads
/etc/tollgate/brand, which a CI checkout has no way to provide. Those are checked as text, failing on a band token or on an SSID written from anything other than a variable — including the nodogsplashgatewayname, which is derived from the same value.Evidence
Red proof, each reverted before the commit:
GATEWAY_NAME="${BRAND_HOSTNAME}-${RANDOM_SUFFIX}-2.4GHz".ssid="TollGate-$RANDOM_SUFFIX"(hardcoded brand).ssidwrite deletedAlso green locally:
js-schema-lint.mjs,build-purity.sh,check-deps-sync.py,check-mirror-sync.py,check-import-paths.py,check-version-sync.sh, andshellcheckon the new script.No production code is changed — the test locks the current behaviour rather than altering it. Docs travel in the same commit (
CHANGELOG.md,CONTRIBUTING.md,AGENTS.md,docs/release-process.md).Card: t_9e5f0b8d