feat: v0.7.0 — config plugins on a converged domain registry#4
Merged
Conversation
Converge ferry's extension mechanisms onto one registry (fn-5), then add seven
config plugins and the observability half on top of it.
fn-5 domain convergence:
- Replace the isZsh oracle and the hardcoded {"iterm2","terminal"} literals with
a single registry (internal/domains, cmd/registry.go) exposing FileDomain and
ResourceDomain; collapse the four file plan arms into one kindFile path.
- Preserve the two-strip contract byte-for-byte (its trigger is now data-driven,
not name-sniffing); delete the dead plugin.Deploy/DeploySpec/OverlayKind
scaffolding. A byte-stable zsh migration eval guards the cutover.
Config plugins:
- git (~/.gitconfig): a hand-written git-INI parser with a machine-identity
firewall — user.email/name/signingkey, gpg.program, credential.helper,
credential.<host>.username, and every [includeIf] block are forced to the
never-shared ~/.gitconfig.local layer; a native [include] overlay; URL and
http.extraHeader token redaction.
- npm: ~/.npmrc carried with registry-token redaction; npm globals as a deps
manager that coexists with brew/apt (names-only, install/reconcile-only).
- tmux (~/.tmux.conf): a per-machine .local sidecar via a source-file directive;
quoted-option (set -g @token '…') secret redaction.
- macOS key bindings (~/Library/KeyBindings/DefaultKeyBinding.dict): a repo-
authoritative single file with plutil/bplist format hygiene.
- Emacs (~/.emacs.d): a repo-authoritative file tree with a volatile-path
exclude filter and a per-file local/emacs overlay.
- iTerm2: Dynamic Profiles JSON as a file-tree domain, plus global prefs via
defaults import with a key allowlist and an "iTerm2 running" guard.
- Homebrew: surface Brewfile drift in status and reconcile the deps scope gating
(install/reconcile-only; no cleanup).
Observability:
- doctor now observes the managed-target invariants (no-symlink / ~/.ssh /
containment) read-only; export labels its reproducible bundle SHA256.
Secrets: a generic column-offset span primitive (secret.SwapColumns) and an npm
auth-line detector back the git/tmux/npm token handling; every credential
surface has a capture eval proving the secret never reaches the shared repo, and
git has an eval proving identity is never shared across machines.
All unit tests, the full eval suite (FERRY_BIN), race tests, and the
docs-currency release gates pass.
BREAKING CHANGE: iTerm2's custom-prefs-folder mechanism is retired. `iterm2 =
true` now imports an allowlist-filtered plist via `defaults import` (apply
refuses while iTerm2 is running) instead of pointing PrefsCustomFolder at the
repo; profiles move to the separate iterm2-profiles Dynamic Profiles domain.
See the CHANGELOG Breaking section.
The git/tmux/npm secret-recogniser tests embed fake, credential-shaped tokens to exercise the scanners and prove a literal token never reaches the shared repo — the same reason internal/secret's tests are already allowlisted. Add the five new fixture-bearing test files by path; every non-test file stays fully scanned.
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.
v0.7.0 — config plugins on a converged domain registry
Implements the signed-off v0.7.0 plan (
docs/plans/2026-07-06-v0.7.0.md): the fn-5domain convergence first, then seven config plugins on the converged registry, plus
the observability half.
fn-5 domain convergence (the enabler)
internal/domains,cmd/registry.go) exposingFileDomain+ResourceDomainreplaces theisZshoracle and the hardcoded{"iterm2","terminal"}literals; the four file plan arms collapse into one
kindFilepath.dead
plugin.Deploy/DeploySpec/OverlayKindscaffolding is deleted. A byte-stablezsh migration eval guards the cutover.
Seven config plugins
~/.gitconfig) — hand-written git-INI parser; identity firewall(
user.email/name/signingkey,gpg.program,credential.helper,credential.<host>.username, and every[includeIf]forced to the never-shared.locallayer); native[include]overlay; URL/http.extraHeadertoken redaction.~/.npmrcwith registry-token redaction; npm globals as a deps manager thatcoexists with brew/apt (names-only, install/reconcile-only).
~/.tmux.confwith asource-file.localsidecar and quoted-option secretredaction.
~/.emacs.d/file tree with a volatile-path excludefilter and a per-file
local/emacs/overlay.defaults importwith a key allowlist and an "iTerm2 running" guard.
status; deps scope gating reconciled.Observability
doctorobserves the managed-target invariants (no-symlink /~/.ssh/ containment),read-only;
exportlabels its reproducible bundle SHA256.Verification
gofmt/go vet/make buildclean;go test ./..., the full eval suite (FERRY_BIN),and
go test -race ./internal/...all green.consistency-lintanddocs-currency-lintclean; the plan is marked shipped. Every credential surface has a capture eval proving the
secret never reaches the shared repo; git has an eval proving identity is never shared
across machines. Reviewed by the security and ruthless reviewers — notably, review (not
tests) caught an npm tarball-spec RCE and two git identity-leak parser bugs, all fixed.
Breaking
iterm2 = truenow imports anallowlist-filtered plist via
defaults import(apply refuses while iTerm2 is running),and profiles move to the separate
iterm2-profilesDynamic Profiles domain. See theCHANGELOG Breaking section.
After merge
The CHANGELOG is pre-promoted to
## [0.7.0] - 2026-07-08and the plan is marked shipped,so
scripts/release.sh v0.7.0can cut the tagged release frommain.Known follow-ups (non-blocking)
init.local.elwith no shared counterpart does not deploy (strict per-shared-fileoverlay); the iterm2-profiles union-walk is the pattern to port over.
PreferenceDomain.Restorelacks the apply-time running-guard (crash-recovery edge).setw/trailing-comment/unquoted tokens(safe — degrades to a refusal, never a leak).
Assisted-by: Claude:claude-opus-4-8