adam-paterson / adam-paterson/dotfiles

PRD: Implement initial portable user environment adoption

Offen
#1 0 Kommentare 0 Reaktionen 0 zugewiesene Personen Auf GitHub ansehen
ready-for-agent
Vorherrschende Sprache
Shell
Sterne
0
Forks
0
PR-Merge-Kennzahlen
Keine gemergten PRs in 30 T.

Beschreibung

## Problem Statement

Adam has a dotfiles repository intended to become the source of truth for a portable user environment across local MacBooks and an Ubuntu VPS, but the current repo is still in a pre-adoption state. Shell startup behavior is mixed across login and universal zsh files, PATH setup is duplicated, the current universal shell startup path can load an ambient 1Password environment, and there is not yet a clear host-profile contract for deciding what should render on a MacBook versus a headless VPS.

As a result, new terminals, non-interactive zsh commands, and agent sessions cannot reliably depend on the same portable tool layer. It is also too easy to accidentally over-own existing local configuration, import broad generated config trees, overwrite vendor snippets, or leak secrets into shells and agents by default.

## Solution

Implement the first safe adoption pass for the portable user environment. This pass establishes explicit host profile data, conservative chezmoi source controls, a small non-secret shell startup contract, and declarative portable tool configuration for aqua and mise.

The implementation should cover only the low-blast-radius batches needed to make the environment reviewable and usable: repo-level chezmoi controls, the non-secret shell floor, and portable tool declarations. It should preserve local/vendor behavior through unmanaged hooks, remove ambient secret loading from universal shell startup, and make the review/apply workflow explicit so future files can be adopted safely.

## User Stories

1. As Adam, I want this dotfiles repo to manage a portable user environment, so that my development setup follows me across MacBooks and Ubuntu VPS hosts.
2. As Adam, I want the repo to avoid whole-machine provisioning, so that it does not take destructive ownership of host-specific system administration.
3. As Adam, I want first-run setup to ask for a reusable host profile, so that MacBook and Ubuntu VPS behavior can vary intentionally.
4. As Adam, I want host instance names to be tracked separately from profiles, so that reusable behavior does not depend on one machine name.
5. As Adam, I want templates to branch on semantic profile data where possible, so that future machines can reuse the same dotfiles without template rewrites.
6. As Adam, I want source-level chezmoi controls before target files are managed, so that host-specific rendering rules are in place before files are applied.
7. As Adam, I want documentation for the safe apply workflow, so that I can review rendered output before overwriting local files.
8. As Adam, I want a small non-secret shared environment core, so that terminals, agents, and non-interactive zsh commands see the same PATH floor.
9. As Adam, I want universal zsh startup to be tiny and silent, so that `zsh -c` commands do not run prompts, completions, or interactive setup.
10. As Adam, I want non-interactive zsh commands to find aqua-installed tools, so that commands launched through zsh can find portable CLIs.
11. As Adam, I want non-interactive zsh commands to find mise shims, so that language runtimes and ecosystem tools work outside interactive shells.
12. As Adam, I want interactive-only shell behavior to live in the interactive shell layer, so that scripts and agents do not depend on aliases, prompts, or completions.
13. As Adam, I want login-only behavior to live in the login shell layer, so that session setup does not pollute every zsh invocation.
14. As Adam, I want Homebrew setup to be gated to MacBook behavior, so that the Ubuntu VPS does not assume macOS tooling.
15. As Adam, I want Ubuntu-specific login bridging to be optional and profile-gated, so that a VPS can use the portable environment even before its login shell is standardized.
16. As Adam, I want Kiro, OrbStack, and similar vendor snippets preserved outside managed files, so that generated app integrations are not committed into the portable source of truth.
17. As Adam, I want unmanaged local shell hooks, so that host-local customizations can survive without editing managed files.
18. As Adam, I want the universal shell startup path to stop sourcing global 1Password environments, so that plain shells and agents do not inherit broad secrets by default.
19. As Adam, I want 1Password usage to remain explicit and scoped, so that secrets are passed only to commands or workflows that need them.
20. As Adam, I want service-account tokens to remain outside chezmoi, so that VPS secret access is not committed, rendered, or printed by dotfiles.
21. As Adam, I want aqua to own standalone CLI binaries, so that portable CLIs can be pinned and updated consistently.
22. As Adam, I want mise to own language runtimes and ecosystem-scoped tools, so that project environments and runtime versions are handled by the right layer.
23. As Adam, I want Homebrew and apt to remain thin host provisioning, so that the dotfiles repo does not become a broad package-management system.
24. As Adam, I want aqua's global config location exported consistently, so that aqua commands and installed tools use the managed configuration.
25. As Adam, I want the aqua bin path to come before mise activation, so that the mise binary can be supplied by aqua.
26. As Adam, I want PATH mutation to be idempotent, so that repeated shell startup does not duplicate path entries.
27. As Adam, I want XDG base directories set consistently, so that portable tool configuration lands in predictable locations.
28. As Adam, I want the first tool declarations to be hand-picked, so that the repo does not import all existing configuration trees.
29. As Adam, I want profile-gated tool declarations where needed, so that MacBook-only tools do not get installed on the VPS.
30. As Adam, I want versions pinned deliberately where reproducibility matters, so that tool updates are intentional and reviewable.
31. As Adam, I want checksum verification deferred until the first package list stabilizes, so that the initial adoption stays focused while leaving a path to stronger supply-chain checks.
32. As Adam, I want the first implementation to cover only low-blast-radius shell and tool basics, so that Git identity, SSH signing, secrets, and bootstrap automation can be reviewed separately.
33. As Adam, I want existing target files inspected before they are replaced, so that meaningful local state is preserved.
34. As Adam, I want dry-run and diff commands documented as part of the workflow, so that first apply is review-first.
35. As Adam, I want managed files applied in small adoption batches, so that each batch can be validated and committed independently.
36. As Adam, I want the shell batch validated with fresh zsh invocations, so that agent and terminal startup behavior is proven externally.
37. As Adam, I want the tool batch validated by installing declared tools, so that the managed aqua and mise configs are actually usable.
38. As Adam, I want no committed plaintext secrets, so that the dotfiles repository is safe to push and review.
39. As Adam, I want no broad ownership of existing config directories, so that app-generated and host-local state remains safe.
40. As Adam, I want future Git/SSH and secret-wrapper work to have a clear foundation, so that higher-risk identity automation can be added later without revisiting the shell floor.

## Implementation Decisions

- Build the feature as the first three adoption batches only: repo safety and host facts, the non-secret shell floor, and portable tool declarations.
- Do not implement Git identity, SSH signing, explicit secret wrappers, or bootstrap/update scripts in this PRD. Those are separate higher-blast-radius changes.
- Add a chezmoi init-time host data contract that records non-secret facts such as profile, host instance name, package manager, GUI expectation, 1Password mode, 1Password SSH agent support, Git signing preference, Git signing mode, and whether a login-shell bridge is allowed.
- Prefer reusable profile fields over host-name branching. Host instance names should exist for rare exceptions only.
- Use two initial profiles: `macbook` for local laptops and `ubuntu-vps` for headless VPS hosts.
- Treat `macbook` as GUI-capable, Homebrew-backed for thin host provisioning, and compatible with the 1Password desktop/SSH-agent flow.
- Treat `ubuntu-vps` as headless, apt-backed for thin host provisioning, and incompatible with desktop 1Password assumptions.
- Keep secret values, service-account tokens, private keys, and generated 1Password state out of chezmoi-managed files.
- Add a coarse host/profile ignore mechanism so documentation, planning assets, and host-inapplicable files are not rendered into the target home.
- Add short operator documentation for the review-first apply workflow rather than exhaustive platform documentation.
- Replace the current shell startup draft with a layered contract: a shared POSIX-compatible environment core, tiny universal zsh startup, login-shell behavior, and interactive-only behavior.
- The shared environment core must be silent, POSIX-compatible, non-secret, and safe for non-interactive commands.
- The shared environment core should set XDG defaults, aqua global config location, and the portable PATH floor.
- PATH entries must be added idempotently and only when appropriate.
- The portable PATH floor should include local user binaries, aqua binaries, mise shims, and user binaries, with macOS Homebrew paths gated to macOS/MacBook behavior.
- Universal zsh startup should source only the shared environment core when readable.
- Universal zsh startup must not run Homebrew, full mise activation, 1Password, prompt setup, completions, aliases, or anything interactive.
- Login-shell behavior should handle login/session concerns and source unmanaged local pre/post hooks for app/vendor snippets.
- Interactive shell behavior should own aliases, completions, prompt initialization, keybindings, fzf/carapace/starship integration if used, and full mise activation.
- Preserve Kiro, OrbStack, and similar app-generated snippets through unmanaged local hooks rather than committing generated snippet bodies.
- Remove the current ambient secret-loading pattern from universal shell startup.
- Use aqua for pinned standalone CLI binaries.
- Use mise for language runtimes, ecosystem-scoped tools, project-local environments, and trusted project roots.
- Keep Homebrew and apt below the portable layer as thin host provisioning mechanisms only.
- Manage only narrow aqua and mise declarations in this pass; do not import the full existing config tree.
- Start from reviewed local tool configuration, but cleanly separate standalone CLI ownership from runtime/ecosystem ownership.
- Avoid Nix, Linuxbrew-by-default, Homebrew-everywhere, mise-only, and aqua-only approaches for this feature.
- First apply must be review-first: inspect rendered output, inspect diff, run dry-run, then apply only reviewed targets.
- Existing differing target files must not be overwritten automatically during first-run adoption.

## Testing Decisions

- Test the feature at the highest practical seam: rendered/applied chezmoi output plus observable shell/tool behavior, not individual template implementation details.
- The primary acceptance seam should be an isolated or reviewable chezmoi render/apply workflow for the supported profile matrix: `macbook` and `ubuntu-vps`.
- A good test verifies external behavior: what files would be rendered, what shell startup emits, what PATH contains, whether secrets are absent, and whether expected tools can be discovered.
- A good test does not assert internal template branching details beyond externally visible behavior.
- Validate host data prompts/config by rendering with both profiles and confirming profile-specific behavior appears only where expected.
- Validate the ignore contract by confirming planning/docs and host-inapplicable managed files are not applied as home-directory targets.
- Validate the shell floor by launching a fresh non-interactive zsh command and checking that the portable PATH floor is available without output, prompts, or secret loading.
- Validate that universal zsh startup does not call 1Password, Homebrew, prompt initialization, completions, or full interactive mise activation.
- Validate that an interactive zsh path can perform full mise activation without requiring agents or scripts to source interactive shell configuration.
- Validate that local/vendor hooks are optional: missing hook files must not fail shell startup.
- Validate that no managed shell file contains resolved secrets or sources a global secret environment.
- Validate tool declarations by running the aqua install flow and the mise install flow after the managed configuration is rendered/applied.
- Validate that aqua-owned tools and mise-owned runtime shims are discoverable from the shell environment.
- Prior art for these tests is the existing wayfinder research and adoption workflow: render templates, inspect diffs, run dry-run apply, apply reviewed targets only, then run behavioral shell/tool commands.
- Because the current repo has no dedicated automated test framework, acceptance may start as documented validation commands. If an automated seam is added, prefer a small shell-based validation script that operates on a disposable home/profile fixture over low-level template unit tests.

## Out of Scope

- Full machine provisioning.
- Nix adoption.
- Broad Homebrew, apt, or Linuxbrew package management.
- Firewall rules, users/groups, SSH daemon policy, server hardening, or system service management.
- Git identity, SSH config, SSH agent integration, and commit-signing automation.
- 1Password service-account creation, vault/environment creation, desktop sign-in, SSH key authorization, or GitHub/GitLab key registration.
- Secret-wrapper commands and project/workflow secret-reference environment files.
- Materializing private keys or resolved secrets.
- Bootstrap/update automation beyond documenting the safe apply workflow.
- Managing all existing configuration directories or app-generated config trees.
- Managing generated 1Password SSH files, mounted local environment files, private keys, or service-account tokens.
- Enabling automatic git push behavior for chezmoi.

## Further Notes

- Domain: personal development environment / dotfiles.
- The guiding shape is a portable user environment with thin host provisioning.
- Standing preferences: no Nix, hand-pick managed files, avoid destructive ownership of existing configuration, prefer boring maintainable tooling, and keep updates easy.
- The main test seam for this PRD is intentionally broad: render/apply the first adoption batches under profile data and verify the resulting shell/tool behavior from the outside.

Beitragsleitfaden

Für dieses Repository ist kein Beitragsleitfaden indexiert

Rechercherichtung

Start by reading the repo’s chezmoi host-profile setup and shell startup template layering to map where macbook vs ubuntu-vps behavior, ignore rules, and unmanaged hooks are defined. Then inspect the shell-floor files plus aqua/mise declaration files described by this PRD to separate non-secret shared env from login/interactive behavior. Run the acceptance flow by rendering and dry-running chezmoi for both profiles, then compare diffs and confirm only expected files are targeted. Done when both profiles behave correctly in non-interactive/interactive zsh (PATH floor, no ambient 1Password source), and the documented review-first apply workflow is in place.

Vom Indexierungsmodell aus dem Issue-Text verfasst.

Bewertung

Tech-Stack
shell, zsh
Bereich
documentation, tooling
Issue-Typ
Feature
Schwierigkeit
4/5
Geschätzter Aufwand
3-5 Tage
Aktivitätsstatus
Ruhig
Klarheit
Größtenteils klar
Anfängerfreundlichkeit
44/100

Neue Issues direkt in Ihr Postfach

Eine kurze Übersicht über anfängerfreundliche GitHub-Issues.