Refresh the bundled OpenAPI spec
The bundled OpenAPI spec at src/mcsinglewire/data/openapi.json is a
frozen snapshot of
https://openapi.icmobile.singlewire.com/api/openapi.json. Refreshing
it changes what’s reachable via api_call — every refresh is a
re-audit trigger
(Safety model § 10).
-
Pull the latest spec
Refresh from upstream make refresh-specThis downloads the upstream JSON and writes it to
src/mcsinglewire/data/openapi.json. Use the Makefile target rather thancurldirectly — the target is the canonical entry point and keeps diffs reviewable. -
Review the diff
Inspect what changed git diff src/mcsinglewire/data/openapi.jsonThings to look for:
- New operationIds — especially new GETs. Some “GETs” have side effects in disguise (Singlewire’s spec sometimes describes simulation, dispatch, or recipient interpolation in the description of a GET). Anything ambiguous is a denylist candidate.
- Renamed or removed operationIds. A failing build will tell you later, but it’s cheaper to notice now.
- Changed scope requirements. The spec annotates each operation
with the OAuth scopes required. A previously-readable endpoint that
now requires
:writeor:managewill start returning 401 — that’s correct behaviour for this server, but worth knowing. - New tags / categories. No action required; they show up in
list_tags()automatically.
-
Scan new GETs against the denylist
The denylist lives in
src/mcsinglewire/server.py:src/mcsinglewire/server.py _GET_DENYLIST: dict[str, str] = {"getScenario": ("Singlewire spec describes a 'simulate answers' mode for this GET ..."),}For every newly-added GET, read its description in the spec carefully. If the wording contains any of the following, the operation belongs on the denylist:
- “simulate”, “dispatch”, “send”, “trigger”, “execute”
- “would be sent”, “would be delivered”
- Anything mentioning recipient interpolation as a side effect of reading
When in doubt, denylist it and ask Singlewire in writing. A denylisted operation can be re-enabled with one line of code; a recipient blast that shouldn’t have happened cannot.
See Add an operation to the denylist for the exact mechanics.
-
Run the test suite
Lint + tests make checktests/test_spec.pyenforces that every operationId is unique — duplicate IDs fail the build before they reach production.tests/test_server.pycovers the validation surface, so a renamed parameter surfaces here too. -
Commit
Commit the snapshot git add src/mcsinglewire/data/openapi.jsongit commit -m "Refresh ICMobile OpenAPI spec ($(date +%Y-%m-%d))"If the diff included denylist changes, group them in the same commit and reference the specific operationIds in the message — it makes the audit trail much easier to read later.
When to refresh
Section titled “When to refresh”There’s no automated trigger. Reasonable cadences:
- Quarterly, as routine maintenance.
- On demand, when Singlewire announces an API addition you want to use.
- Before any audit, so the bundled spec matches the live API at audit time.
The refresh is a re-audit trigger — see Safety model § 10. After a refresh, walk through the safety model before resuming use.