Provision lock-guard to clients on demand via SSH — restore zero-footprint client model - #30
Merged
twistedmelonman merged 6 commits intoAug 12, 2026
Conversation
added 5 commits
August 12, 2026 13:38
Pushes lock-guard's file content over SSH on demand (checksum-compared first), so clients never clone this repo or run an install step.
…tomic push, payload verification) - CLAUDE.md/README.md: correct the "upgrade path" and Chrome-permission docs, which still implied clients need bin/install or a repo clone. Clients are provisioned automatically and on-demand by lock-fanout's provision_host, not by install. - bin/lock-fanout: add a fail-fast guard for a missing/unreadable local lock-guard in provision_host, before any shasum/ssh call, closing a zero-byte-push risk. Make the client-side push atomic (write to a temp file, chmod, then mv into place) so a truncated transfer never leaves a partial-but-executable lock-guard on the client. Document the intentional local/remote shasum asymmetry. - tests/lock-fanout.bats: add coverage for the missing-local-lock-guard guard clause, and assert the pushed content actually matches bin/lock-guard rather than just the shape of the push command.
"missing local lock-guard" test's `run !` result was never checked, making its no-ssh-call assertion inert regardless of guard behavior. "three clients all succeed" always exercised the push path (no checksum was scripted to match), despite its name implying the steady-state no-push case. Added STUB_SSH_CHECKSUM_ALL_MATCH to the ssh stub so multi-host tests can exercise "already current" for every client, and asserted no push occurs in that test. Claude-Session: https://claude.ai/code/session_01Sasr2N9Rj9n8rv2sjwN2YJ
…-log assertions The prior commit's bare `!` negation was being silently reverted back to `run !` by the repo's shell-lint-fix pre-commit hook on each commit attempt, so the intended fix never actually landed despite two prior commit messages claiming it had. Switched both negative assertions (the missing-local-lock-guard "no shasum call" check and the new "no push in steady state" check) to the `run` + `[ "$status" -ne 0 ]` pattern already used successfully elsewhere in this file, which the hook does not touch. Verified both catch real regressions via a break-test: temporarily disabling the missing-file guard, and separately forcing an unconditional push, each correctly fails the corresponding test; both pass again once reverted. Claude-Session: https://claude.ai/code/session_01Sasr2N9Rj9n8rv2sjwN2YJ
|
BLOCK: provision_host returns 1 for missing remote file (shasum exits 1 on file-not-found, SSH propagates it, rc!=0 fires return 1). New clients never get provisioned. VERDICT: BLOCK |
This comment has been minimized.
This comment has been minimized.
…rovision_host The remote shasum check exited 1 (and so did ssh) whenever a brand-new client had never had lock-guard installed, identical to a genuine SSH connection failure. That permanently routed new clients to the bare pmset fallback instead of ever provisioning them. Pipe the remote shasum through `|| true` so a missing file yields exit 0 with empty output, letting ssh's exit code reflect only connection success/failure.
|
<!-- claude-blocking-review sha=3e4ce3cf8ef5aa5e4d51a6e69fc97180b0c35a1f run=31643596214 --> |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PR #25 changed
lock-fanoutto invoke a newlock-guardscript on each client over SSH, but silently broke this project's deployment model: clients previously needed zero footprint (no git clone, no install, just a stock macOSpmsetand an SSH key) — after #25, every client neededlock-guardsymlinked viabin/install, which requires cloning this repo onto every client. That's not the model and isn't going to become the model.This PR restores zero-footprint clients:
lock-fanoutnow provisions each client on demand, at lock time, by pushingbin/lock-guard's content directly over SSH — checksum-compared first (shasum -a 256) so the push only happens when missing or stale. Clients never clone this repo.provision_host(host, user)inbin/lock-fanout: checksum-check → skip if current, atomic push (temp file +mv -f) if missing/stale,mkdir -p ~/.local/binfor never-before-provisioned clients.pmset displaysleepnowcall for that client that cycle — logged distinctly (warn=provision-failed) — rather than attempting alock-guardcall that would fail the same way Suppress screen lock during meetings (lock-guard) #25's regression did. The client still locks, just without meeting-suppression for that cycle.bin/lock-guarditself is unchanged — only its delivery mechanism changes.Review history
Went through task review, a final whole-branch review (2 Important findings: stale
CLAUDE.mddoc contradicting the branch's purpose, and a missing-local-file edge case that could push a zero-byte no-op instead of failing safely — both fixed), and the local pre-push hook caught two silent test gaps (arun !assertion whose result was never checked, and a test that always exercised the push path despite its name implying steady-state). All fixed and verified via break-tests (temporarily reintroducing each bug to confirm the test now catches it).Filed as follow-ups, not blocking:
user@host(latent test-infra limitation, not a product bug)warn=provision-faileddoesn't distinguish "client unreachable" from "client lacks shasum" in the logTest plan
bats tests/— 58/58 passingshellcheck -S info bin/*— cleanhttps://claude.ai/code/session_01Sasr2N9Rj9n8rv2sjwN2YJ