Relocate ControlMaster config into its own feature directory#26
Open
ai-cora wants to merge 1 commit into
Open
Conversation
Previously the ControlMaster feature was split across two locations:
hosts/controlmaster.conf (cross-cutting transport config sitting in
the host-specific config directory) and a top-level sockets/ runtime
dir with no README. The naming didn't communicate intent — every new
user asking "which kind of socket lives in sockets/?" was a signal.
After this change every keycutter feature is a directory with its
own README and artefacts:
hosts/ — host configs (existing pattern)
agents/ — ssh-agent profiles + runtime sockets (existing
pattern: profile dirs each contain ssh-agent.socket)
controlmaster/ — ControlMaster config + runtime sockets + README
(NEW — matches the existing pattern)
Changes:
- ssh_config/keycutter/controlmaster/controlmaster.conf
moved from ssh_config/keycutter/hosts/. ControlPath updated to
~/.ssh/keycutter/controlmaster/sockets/%r@%h:%p
- ssh_config/keycutter/controlmaster/README.md
new — Purpose / Structure / Configuration / Security /
Disabling / Related
- ssh_config/keycutter/controlmaster/sockets/.gitkeep
placeholder so the dir exists post-install (SSH won't create
the ControlPath parent for itself)
- ssh_config/keycutter/keycutter.conf
Include keycutter/controlmaster/*.conf added alongside the
existing hosts include, with a short comment explaining the
per-feature-directory pattern
- ssh_config/keycutter/hosts/README.md
removed controlmaster.conf from the directory listing; added a
note pointing at the sibling controlmaster/ feature dir
- bin/keycutter:196
dir-ensure now creates controlmaster/sockets/ instead of the
old top-level sockets/
- test/test_helper.bash:21,122
fixture mkdir now includes controlmaster/sockets/ in the brace
expansion (both sites)
All 109 bats tests pass.
Backwards compatibility / upgrade path: users with an existing
~/.ssh/keycutter/ will have an orphan hosts/controlmaster.conf and
a top-level sockets/ after this lands. SSH first-match-wins means
the orphan would still be the active config, so the post-install
manual cleanup is:
cd ~/.ssh/keycutter
git rm hosts/controlmaster.conf
rmdir sockets/
A follow-up feature (skillbox SKB-455) will teach keycutter-install
to detect well-known orphan files and offer to migrate them so this
becomes automatic.
Task: KC-68 (cora-7/Mike taskmaster store)
Related: github.com/mbailey/skillbox SKB-419 (keycutter skill epic)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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
Move
ssh_config/keycutter/hosts/controlmaster.confand the top-levelsockets/runtime dir into a single, self-explanatorycontrolmaster/feature directory. After this change every keycutter feature is a directory with its own README and artefacts:hosts/— host configs (existing)agents/— ssh-agent profiles + runtime sockets (existing)controlmaster/— ControlMaster config + runtime sockets + README (new — matches the existing pattern)Motivation
The trigger was a real-world question: "why are there two sockets in
~/.ssh/keycutter/?" The answer required walking through the layout — one socket is the ControlMaster multiplex socket under top-levelsockets/, the other is the per-bundle ssh-agent socket underagents/<profile>/ssh-agent.socket. They serve completely different purposes (transport multiplexing vs identity isolation), but the layout didn't say so.Two specific problems:
sockets/had no README and the name didn't disambiguate which kind of socket.hosts/controlmaster.confwas in the wrong directory.hosts/README.mddescribes that directory as for "host-specific SSH behavior", but ControlMaster is a cross-cutting transport concern that just happens to be expressed viaHostblocks. It was the odd one out.After this change the answer to "what is this directory?" is immediate for every directory in the tree.
Changes
ssh_config/keycutter/controlmaster/controlmaster.conf— moved fromhosts/.ControlPathupdated to~/.ssh/keycutter/controlmaster/sockets/%r@%h:%pssh_config/keycutter/controlmaster/README.md— new. Purpose / Structure / Configuration / Security / Disabling / Relatedssh_config/keycutter/controlmaster/sockets/.gitkeep— placeholder so the directory exists post-install (SSH won't create theControlPathparent)ssh_config/keycutter/keycutter.conf—Include keycutter/controlmaster/*.confadded alongside the existing hosts include, with a short comment explaining the per-feature-directory patternssh_config/keycutter/hosts/README.md— removedcontrolmaster.conffrom the directory listing; added a sentence pointing at the siblingcontrolmaster/feature dirbin/keycutter:196—dir-ensurenow createscontrolmaster/sockets/instead of the old top-levelsockets/test/test_helper.bash:21,122— fixturemkdirnow includescontrolmaster/sockets/in the brace expansion (both sites)Upgrade path for existing installs
Users with an existing
~/.ssh/keycutter/will end up with an orphanhosts/controlmaster.confand a top-levelsockets/after this lands. SSH first-match-wins means the orphan would still be the active config, so the post-install manual cleanup is:A follow-up enhancement (planned out-of-band) will teach the install path to detect well-known orphans and offer to migrate them, so this becomes automatic for future layout changes.
Test plan
make test— all 109 bats tests pass locallyssh -G <host>resolvesControlPathto the new locationkeycutter(thebin/keycuttertool) createscontrolmaster/sockets/instead ofsockets/on a fresh installcontrolmaster/controlmaster.confis picked up by SSH via the newIncludeline🤖 Generated with Claude Code