Skip to content

Namespace the appdata path, and pin the unusable-port case - #83

Merged
QuiteYellow merged 1 commit into
mainfrom
fix/env-drift-and-zero-port
Sep 8, 2026
Merged

Namespace the appdata path, and pin the unusable-port case#83
QuiteYellow merged 1 commit into
mainfrom
fix/env-drift-and-zero-port

Conversation

@QuiteYellow

Copy link
Copy Markdown
Owner

Three things that only show up as a failure once it is too late to see them.

docker-compose.yml interpolated a bare APPDATA_DIR into the /config bind mount. Compose gives a shell-exported variable precedence over the project's .env, so a docker compose up run by hand from a shell that had sourced a sibling project's .env would mount that project's directory here. The wrong path then freezes into the container until it is recreated, and nothing logs it. deploy.sh is immune, since ssh does not forward the environment, so this could only ever bite an interactive run.

The variable is SMARTTHINGS_LOCAL_APPDATA_DIR now, renamed in .env.example, docker-compose.yml and deploy.sh together so the :? guard fails loudly rather than falling through to the ./certs default. deploy.sh keeps a short local name internally; nothing exports it, so Compose never sees it.

DEBUG_BRIDGE was read by bridge.py and documented nowhere. The only way to find it was to grep the source. .env.example describes it now.

tests/test_ocf_discovery.py had no case for a policy port the library cannot use. Zero is the one the hardware produces: RT-OCF binds the DTLS socket with port 0 and learns the assignment through getsockname, so a directory serialised before that bind advertises sec: true, port: 0. A plaintext read on my reference dryer has returned exactly that, while a later read of the same device gave a real port. Absence is the right answer, because it surfaces as no_secure_ports and leaves the caller free to retry rather than sending a handshake at port 0. A bool needs rejecting in the same breath, or True passes for port 1. A second case covers one unusable port alongside a usable one, so a single bad link cannot discard the rest of a reduced directory.

While in the deploy.sh header: two stale convention paths, and a bootstrap snippet whose source .env no longer resolved the key it went on to use.

Tested: 769 tests pass, check_share_safety.py --changed-since main clean. Deployed to my Unraid bridge and recreated the container: /config resolves to /mnt/user/appdata/smartthings-local with both certs visible, no ./certs fallback directory got created, and both appliances reconnected and seeded clean.

https://claude.ai/code/session_01UJBUFo8zZWrebGqf6gUzcL

Three things this file and its neighbours got wrong, none of which shows
up as a failure until it matters.

docker-compose.yml interpolated a bare APPDATA_DIR into the /config bind
mount. Compose prefers a shell-exported variable over the project's .env,
so running docker compose up by hand from a shell that had sourced a
sibling project's .env would mount that project's directory here. The
wrong path then freezes into the container until it is recreated, with
nothing logged. deploy.sh is immune because ssh does not forward the
environment, so this only ever bit an interactive run. The variable is
SMARTTHINGS_LOCAL_APPDATA_DIR now, in .env.example, docker-compose.yml
and deploy.sh together, which is a name no other project can shadow.
deploy.sh keeps its own short local name; nothing exports it, so Compose
never sees it.

DEBUG_BRIDGE was read by bridge.py and documented nowhere, so the only
way to find it was to grep the source.

tests/test_ocf_discovery.py had no case for a policy port it cannot use.
Zero is the one the hardware produces: RT-OCF binds the DTLS socket with
port 0 and learns the assignment through getsockname, so a directory
serialised before that bind advertises sec true with port 0. A plaintext
read on the reference dryer here has returned exactly that while a later
read of the same device gave a real port. Absence is the right answer,
because it surfaces as no_secure_ports and leaves the caller free to
retry, and a bool has to be rejected too or True passes for port 1.

The deploy.sh header also named two stale convention paths and a bare
source .env that no longer resolves the key it goes on to use.

Claude-Session: https://claude.ai/code/session_01UJBUFo8zZWrebGqf6gUzcL
@QuiteYellow
QuiteYellow merged commit ef051c4 into main Sep 8, 2026
8 checks passed
@QuiteYellow
QuiteYellow deleted the fix/env-drift-and-zero-port branch September 8, 2026 19:41
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant