Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,8 @@ jobs:
go-version-file: src/go.mod
- name: Build purity check
run: bash tests/contract/build-purity.sh
- name: Shipped AP SSID format check
run: bash tests/contract/check-ssid-format.sh

deps-and-imports:
runs-on: ubuntu-latest
Expand Down
2 changes: 2 additions & 0 deletions .ngit/act/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,8 @@ jobs:
go-version-file: src/go.mod
- name: Build purity check
run: bash tests/contract/build-purity.sh
- name: Shipped AP SSID format check
run: bash tests/contract/check-ssid-format.sh

deps-and-imports:
runs-on: ubuntu-latest
Expand Down
7 changes: 4 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,10 @@ get wrong:
and silently skips all subpackages. One implementation:
[scripts/go-battery.sh](scripts/go-battery.sh).

If the change touches the config schema or captive-portal contract,
also run `node tests/contract/js-schema-lint.mjs` and
`bash tests/contract/build-purity.sh` from the repo root.
If the change touches the config schema, the captive-portal contract
or a shipped default, also run `node tests/contract/js-schema-lint.mjs`,
`bash tests/contract/build-purity.sh` and
`bash tests/contract/check-ssid-format.sh` from the repo root.
- PRs are squash-merged; the maintainer rewrites the final commit
message.

Expand Down
22 changes: 22 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1251,6 +1251,27 @@ and [Semantic Versioning](https://semver.org/).
requires `testenv` again
([#584](https://github.com/OpenTollGate/tollgate-module-basic-go/pull/584)).

- **The open-AP SSID format is now a checked contract.** `99-tollgate-setup`
names the access point `<brand>-<device code>` (`TollGate-A1B2` for the
default brand — the code is the four `[A-Z0-9]` characters minted once and
stored per the one-device-code decision) and puts that same name on both
radios, so `tests/contract/check-ssid-format.sh` — a CI gate, also wired
into `hooks/pre-commit` — now fails when that stops being true. It sources
the real `load_brand()` → `setup_device_identity()` → `setup_public_wifi()`
chain out of the script, runs it against a stub `uci` that renders
`uci show` section types bare like the real one, and asserts the SSIDs it
actually writes: both radios' APs matching `^TollGate-[A-Z0-9]{4}$` for
the default brand, one shared name, and a code that is minted per fresh
device and then reused from the store across runs. A second, structural
layer checks the assignment sites a checkout cannot execute — the
same-version reinstall path converges the SSID from the stored code, and
the whitelabel branch reads `/etc/tollgate/brand` — so neither branch can
quietly acquire a band suffix. That suffix is the drift the test exists
for: the Go side keys on the `TollGate-` prefix (`discovery_log.go`,
`vendor_element_manager.go`), and `TollGate-A1B2-2.4GHz` would be a second
network identity for the same router
([#524](https://github.com/OpenTollGate/tollgate-module-basic-go/pull/524)).


## [v0.6.0-alpha4] - 2026-09-22

Expand Down Expand Up @@ -1531,6 +1552,7 @@ same-version short branch.
occurrence (a literal sentinel in the case pattern) being rewritten by the
global packaging substitution. Complements the substitution-proof gate from
#463; comment mentions stay exempt.

- **Recorded the captive-portal bundle-location decision.** The portal is
consumed as a hash-pinned CI-built artifact rather than merged into this
repo; the stale `portal.commit` pin and the guest-SPA-only
Expand Down
7 changes: 4 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,13 +177,14 @@ channel and breaks the apk version. The maintainer runbook for cutting
and publishing a release lives in
[docs/release-process.md](docs/release-process.md).

If your change touches the config schema or the captive-portal
contract, also run the contract checks from the repo root (these are
CI gates):
If your change touches the config schema, the captive-portal contract
or a shipped default, also run the contract checks from the repo root
(these are CI gates):

```bash
node tests/contract/js-schema-lint.mjs
bash tests/contract/build-purity.sh
bash tests/contract/check-ssid-format.sh
```

**Recommended for router-visible changes**: build a real package with
Expand Down
26 changes: 26 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,32 @@ Key fields:
are probed. `ignore_interfaces` typically needs to list any wireless
interfaces *the router itself serves on* to prevent self-probing.

## SSID conventions

On first boot the router derives its Wi-Fi names from a single generated
device code (see [#605](https://github.com/OpenTollGate/tollgate-module-basic-go/pull/605)
and `docs/architecture/one-device-code.md`).

- **Public open AP** — `TollGate-XXXX`, e.g. `TollGate-9C3F`. The `XXXX` is
the four-character device code of `[A-Z0-9]`, minted once on first boot.
Both the 2.4 GHz and 5 GHz radios advertise the **same** SSID (band
steering), so clients are handed off between radios seamlessly.
- **Private management AP** — `c08r4d0r-XXXX` (same `XXXX` device code as
the public AP), WPA2/PSK. Both radios share it. The passphrase is a
memorable `Word-Word-Word-NN` string set on first boot and preserved on
upgrade. The `c08r4d0r` prefix is the project's generic default nym —
every installation shares it, so it names the product rather than any
operator; an operator who personalizes the nym does so as a visible
choice. [#531](https://github.com/OpenTollGate/tollgate-module-basic-go/pull/531)
proposed renaming this default and was closed as superseded by that
decision.
- **nodogsplash name** — the captive-portal gate shows
`TollGate-XXXX Portal` as its `gatewayname`.

Branding: a whitelabel installer can pin `/etc/tollgate/brand` to `net4sats`,
which swaps the `TollGate` prefix for that brand's name everywhere. The
public AP format is pinned by `tests/contract/check-ssid-format.sh`.

## Testing

Unit tests, from the [src/](src/) directory:
Expand Down
5 changes: 3 additions & 2 deletions docs/release-process.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,13 @@ go build ./...
go test -race -count=1 -tags testenv ./...
```

From the repo root, when the change touches the config schema or the
captive-portal contract (these are CI gates):
From the repo root, when the change touches the config schema, the
captive-portal contract or a shipped default (these are CI gates):

```bash
node tests/contract/js-schema-lint.mjs
bash tests/contract/build-purity.sh
bash tests/contract/check-ssid-format.sh
```

From the repo root, always:
Expand Down
10 changes: 10 additions & 0 deletions hooks/pre-commit
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,13 @@ if git diff --cached --name-only | grep -q '\.go$'; then
exit 1
fi
fi

# The open AP's SSID is written into the beacon of every router that takes the
# default, and it is the name clients and the operator match on — keep it the
# contract shape (`<brand>-<4 hex chars>`) so a band suffix or a fixed literal
# cannot come back. Runs whenever anything under packaging/files/ is staged:
# that tree is what the .ipk/.apk payload is staged from.
if git diff --cached --name-only | grep -qE '^packaging/files/'; then
echo "🔍 Checking the AP SSID format contract..."
bash tests/contract/check-ssid-format.sh
fi
Loading