Skip to content

Provision lock-guard to clients on demand via SSH — restore zero-footprint client model - #30

Merged
twistedmelonman merged 6 commits into
mainfrom
claude/feat-lock-guard-remote-provisioning
Aug 12, 2026
Merged

twistedmelonman merged 6 commits into
mainfrom
claude/feat-lock-guard-remote-provisioning

Conversation

@twistedmelonman

Copy link
Copy Markdown
Member

Summary

PR #25 changed lock-fanout to invoke a new lock-guard script 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 macOS pmset and an SSH key) — after #25, every client needed lock-guard symlinked via bin/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-fanout now provisions each client on demand, at lock time, by pushing bin/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.

  • New provision_host(host, user) in bin/lock-fanout: checksum-check → skip if current, atomic push (temp file + mv -f) if missing/stale, mkdir -p ~/.local/bin for never-before-provisioned clients.
  • If provisioning itself fails (client unreachable, etc.), falls back to a direct pmset displaysleepnow call for that client that cycle — logged distinctly (warn=provision-failed) — rather than attempting a lock-guard call 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-guard itself is unchanged — only its delivery mechanism changes.

Review history

Went through task review, a final whole-branch review (2 Important findings: stale CLAUDE.md doc 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 (a run ! 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:

Test plan

  • bats tests/ — 58/58 passing
  • shellcheck -S info bin/* — clean
  • Break-tested both new negative assertions (missing-file guard, steady-state no-push) by temporarily reintroducing the bug each guards against — both correctly fail, then pass again once reverted

https://claude.ai/code/session_01Sasr2N9Rj9n8rv2sjwN2YJ

Claude Code Bot 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
@claude

claude Bot commented Aug 12, 2026

Copy link
Copy Markdown

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

@claude

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

claude Bot commented Aug 12, 2026

Copy link
Copy Markdown

<!-- claude-blocking-review sha=3e4ce3cf8ef5aa5e4d51a6e69fc97180b0c35a1f run=31643596214 -->

@twistedmelonman
twistedmelonman merged commit 6b9b954 into main Aug 12, 2026
4 checks passed
@twistedmelonman
twistedmelonman deleted the claude/feat-lock-guard-remote-provisioning branch August 12, 2026 21:58
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