Skip to content

feat: v0.7.0 — config plugins on a converged domain registry#4

Merged
REPPL merged 3 commits into
mainfrom
feat/v0.7.0-config-plugins
Jul 8, 2026
Merged

feat: v0.7.0 — config plugins on a converged domain registry#4
REPPL merged 3 commits into
mainfrom
feat/v0.7.0-config-plugins

Conversation

@REPPL

@REPPL REPPL commented Jul 8, 2026

Copy link
Copy Markdown
Owner

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-5
domain convergence first, then seven config plugins on the converged registry, plus
the observability half.

fn-5 domain convergence (the enabler)

  • One registry (internal/domains, cmd/registry.go) exposing FileDomain +
    ResourceDomain replaces the isZsh oracle and the hardcoded {"iterm2","terminal"}
    literals; the four file plan arms collapse into one kindFile path.
  • The two-strip contract is preserved byte-for-byte (its trigger is now data-driven);
    dead plugin.Deploy/DeploySpec/OverlayKind scaffolding is deleted. A byte-stable
    zsh migration eval guards the cutover.

Seven config plugins

  • git (~/.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
    .local layer); native [include] overlay; URL/http.extraHeader token redaction.
  • npm~/.npmrc with registry-token redaction; npm globals as a deps manager that
    coexists with brew/apt (names-only, install/reconcile-only).
  • tmux~/.tmux.conf with a source-file .local sidecar and quoted-option secret
    redaction.
  • macOS key bindings — repo-authoritative single file with plutil/bplist hygiene.
  • Emacs — repo-authoritative ~/.emacs.d/ file tree with a volatile-path exclude
    filter and a per-file local/emacs/ overlay.
  • iTerm2 — Dynamic Profiles JSON file-tree domain + global prefs via defaults import
    with a key allowlist and an "iTerm2 running" guard.
  • Homebrew — Brewfile drift surfaced in status; deps scope gating reconciled.

Observability

  • doctor observes the managed-target invariants (no-symlink / ~/.ssh / containment),
    read-only; export labels its reproducible bundle SHA256.

Verification

gofmt/go vet/make build clean; go test ./..., the full eval suite (FERRY_BIN),
and go test -race ./internal/... all green. consistency-lint and docs-currency-lint
clean; 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's custom-prefs-folder mechanism is retired; iterm2 = true now imports an
    allowlist-filtered plist via defaults import (apply refuses while iTerm2 is running),
    and profiles move to the separate iterm2-profiles Dynamic Profiles domain. See the
    CHANGELOG Breaking section.

After merge

The CHANGELOG is pre-promoted to ## [0.7.0] - 2026-07-08 and the plan is marked shipped,
so scripts/release.sh v0.7.0 can cut the tagged release from main.

Known follow-ups (non-blocking)

  • Emacs init.local.el with no shared counterpart does not deploy (strict per-shared-file
    overlay); the iterm2-profiles union-walk is the pattern to port over.
  • iTerm2 PreferenceDomain.Restore lacks the apply-time running-guard (crash-recovery edge).
  • tmux secret recognizer does not span-capture setw/trailing-comment/unquoted tokens
    (safe — degrades to a refusal, never a leak).
  • The iTerm2 global-plist allowlist is a curated starter set to extend to taste.

Assisted-by: Claude:claude-opus-4-8

REPPL added 3 commits July 8, 2026 07:58
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.
@REPPL REPPL merged commit 6c5ccdd into main Jul 8, 2026
11 checks passed
@REPPL REPPL deleted the feat/v0.7.0-config-plugins branch July 8, 2026 07:09
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