diff --git a/.specify/feature.json b/.specify/feature.json index 875e197..c317006 100644 --- a/.specify/feature.json +++ b/.specify/feature.json @@ -1,3 +1,3 @@ { - "feature_directory": "specs/003-dependency-policy-ci" + "feature_directory": "specs/004-macos12-macports-support" } diff --git a/specs/004-macos12-macports-support/checklists/requirements.md b/specs/004-macos12-macports-support/checklists/requirements.md new file mode 100644 index 0000000..3cd19cf --- /dev/null +++ b/specs/004-macos12-macports-support/checklists/requirements.md @@ -0,0 +1,34 @@ +# Specification Quality Checklist: macOS 12 MacPorts Support + +**Purpose**: Validate specification completeness and quality before proceeding to planning +**Created**: 2026-08-03 +**Feature**: [spec.md](../spec.md) + +## Content Quality + +- [x] No implementation details (languages, frameworks, APIs) +- [x] Focused on user value and business needs +- [x] Written for non-technical stakeholders +- [x] All mandatory sections completed + +## Requirement Completeness + +- [x] No [NEEDS CLARIFICATION] markers remain +- [x] Requirements are testable and unambiguous +- [x] Success criteria are measurable +- [x] Success criteria are technology-agnostic (no implementation details) +- [x] All acceptance scenarios are defined +- [x] Edge cases are identified +- [x] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +## Feature Readiness + +- [x] All functional requirements have clear acceptance criteria +- [x] User scenarios cover primary flows +- [x] Feature meets measurable outcomes defined in Success Criteria +- [x] No implementation details leak into specification + +## Notes + +- Validation passed on 2026-08-03. The specification is ready for `$speckit-plan`. diff --git a/specs/004-macos12-macports-support/contracts/macos-target-selection.md b/specs/004-macos12-macports-support/contracts/macos-target-selection.md new file mode 100644 index 0000000..66e27b6 --- /dev/null +++ b/specs/004-macos12-macports-support/contracts/macos-target-selection.md @@ -0,0 +1,44 @@ +# Contract: macOS Target Selection + +## Purpose + +The macOS dependency installer must classify the host before dependency preflight so Monterey receives the +legacy MacPorts-aware path and newer macOS releases keep their existing behavior. + +## Inputs + +- macOS product version. +- Machine architecture. +- Machine role selected during chezmoi initialization. +- Dependency-management enabled/disabled choice. +- Presence and discoverability of the MacPorts `port` command when the selected source requires MacPorts. + +## Ordered behavior + +1. If dependency management is disabled, exit successfully before package-manager checks, network access, + installation, or state writes. +2. Detect macOS major version and CPU architecture. +3. If the major version is `12`, classify the target as Monterey legacy macOS and set the package-management + path to MacPorts-aware. +4. If the major version is newer and already supported by the repository, retain the existing macOS path. +5. If the architecture is not `x86_64` or `aarch64`, return `target-unsupported` before mutation. +6. Apply workstation/server role filtering before resolving dependency sources. +7. When at least one selected source requires MacPorts, validate `port` availability before preflight. +8. Return a structured diagnostic that includes macOS release category, architecture, role, selected package + path, and next action whenever target selection blocks setup. + +## Result classes + +| Result | Meaning | Mutation allowed | +|---|---|---| +| `target-selected` | A supported macOS target and role were selected. | Not yet; proceed to preflight | +| `disabled` | Dependency management is disabled. | No mutation; successful exit | +| `prerequisite-blocked` | Monterey selected a MacPorts-required path but `port` is missing, hidden, or unusable. | No | +| `target-unsupported` | macOS version or architecture has no declared handling. | No | + +## Safety invariants + +- Do not use Homebrew as an implicit fallback on Monterey. +- Do not route newer macOS releases into the Monterey path by accident. +- Do not mutate dependencies or machine-local state until target selection and prerequisites succeed. +- Do not install MacPorts automatically; provide documented user action instead. diff --git a/specs/004-macos12-macports-support/contracts/monterey-reconciliation.md b/specs/004-macos12-macports-support/contracts/monterey-reconciliation.md new file mode 100644 index 0000000..b4ed3b7 --- /dev/null +++ b/specs/004-macos12-macports-support/contracts/monterey-reconciliation.md @@ -0,0 +1,55 @@ +# Contract: Monterey Dependency Reconciliation + +## Purpose + +Monterey dependency reconciliation extends the existing policy model with MacPorts-aware prerequisites and +conflict diagnostics while preserving official artifact compatibility and user-owned software. + +## Inputs + +- Selected macOS target from the macOS target-selection contract. +- Valid dependency compatibility manifest. +- Role-filtered managed dependency list. +- Active executable/font state, including candidate duplicate paths. +- MacPorts prerequisite state when a selected dependency source requires it. +- Machine-local retain override state. + +## Ordered behavior + +1. Select each applicable dependency source from the manifest. +2. Prefer a declared official artifact when it is compatible with Monterey and checksum-verifiable. +3. Use a MacPorts native package only when the manifest explicitly declares a MacPorts source for that + dependency and target. +4. If a MacPorts source is selected, verify the MacPorts prerequisite before package or artifact preflight. +5. Observe active installations and classify each active path as managed user-local, MacPorts, Homebrew, + manual, font registry, absent, or unknown. +6. Report active Homebrew/manual conflicts when they affect compatibility; do not remove them automatically. +7. Preflight every selected artifact/package and collect all failures before mutation. +8. Apply changes in manifest order only after the complete applicable preflight succeeds. +9. Verify the active executable version or font asset after each change. +10. On success, report compatible or explicitly unsupported status according to retained-version state. + +## Required diagnostics + +Every blocked Monterey diagnostic includes: + +```text +Dependency: +Expected: +Observed: +Target: macOS 12 Monterey/// +Next action: +``` + +Mixed-manager diagnostics additionally include the active path and the selected package-management path so +users can understand whether Homebrew, MacPorts, a managed artifact, or a manual binary is currently taking +precedence. + +## Safety invariants + +- Never silently substitute Homebrew for MacPorts on Monterey. +- Never silently substitute a different package or artifact version. +- Never remove Homebrew, MacPorts, or manual installations outside explicitly managed locations. +- Never install workstation-only GUI terminals or fonts for the server role. +- Never claim Monterey compatibility until every applicable active dependency is verified or a documented + unsupported-retain state exists. diff --git a/specs/004-macos12-macports-support/data-model.md b/specs/004-macos12-macports-support/data-model.md new file mode 100644 index 0000000..da4ce72 --- /dev/null +++ b/specs/004-macos12-macports-support/data-model.md @@ -0,0 +1,121 @@ +# Data Model: macOS 12 MacPorts Support + +## MacOSTarget + +The normalized macOS machine identity used before dependency resolution. + +| Field | Type | Rules | +|---|---|---| +| `os` | literal | Always `darwin` for this feature. | +| `majorVersion` | integer | `12` selects the Monterey legacy path; newer supported versions retain existing behavior. | +| `releaseName` | enum | `monterey` when `majorVersion` is `12`; otherwise `newer-macos` for this feature's regression scope. | +| `arch` | enum | `x86_64` or `aarch64`; unknown architecture is blocked before mutation. | +| `role` | enum | `workstation` or `server`; role filters dependencies before preflight. | +| `packageFamily` | enum | `macports` for Monterey when native package management is required; existing macOS family for newer releases. | + +Validation rules: + +- macOS 12 must not be routed through the newer macOS package-management path by default. +- Newer macOS must not enter the Monterey path unless explicitly selected by a documented override. +- Unknown macOS major version or CPU architecture must produce an actionable blocked diagnostic rather than + guessing. + +## LegacyPackagePrerequisite + +The prerequisite state for Monterey package-management operations. + +| Field | Type | Rules | +|---|---|---| +| `manager` | literal | `macports`. | +| `command` | string | `port`. | +| `expectedPrefix` | path | Default expected prefix is `/opt/local`. | +| `status` | enum | `available`, `missing`, `not-on-path`, `unusable`. | +| `observedPath` | path/null | The discovered `port` executable path when present. | +| `observedVersion` | string/null | Result of a version probe when available. | +| `nextAction` | string | English instruction for installing, opening a new shell, or fixing PATH. | + +Validation rules: + +- A missing or unusable prerequisite blocks before dependency preflight and mutation. +- The diagnostic must identify the selected package-management path and the next action. +- The prerequisite record must not imply that Homebrew is an acceptable Monterey fallback. + +## DependencySourceSelection + +The selected source for a managed dependency on a specific Monterey target. + +| Field | Type | Rules | +|---|---|---| +| `dependencyId` | string | Must match an existing managed dependency ID. | +| `target` | MacOSTarget | Monterey target plus role and architecture. | +| `strategy` | enum | `official-artifact`, `native-package`, or `platform-exception`. | +| `manager` | enum/null | `macports` only when `strategy` is `native-package`; null for official artifacts. | +| `version` | string | Exact declared compatible version; never `latest`. | +| `verification` | object | Executable version probe or font hash requirements from the dependency policy. | +| `requiresPrerequisite` | boolean | True when the selected source needs MacPorts before mutation. | + +Validation rules: + +- Official artifacts remain valid on Monterey only when their declared archive and member are compatible with + the target architecture and checksum verification passes. +- Native MacPorts package selections require an exact compatible package declaration and an available + MacPorts prerequisite. +- A dependency may not silently switch to an undeclared source or version. + +## ActiveMacOSInstallation + +The active executable or asset observed on the Monterey machine. + +| Field | Type | Rules | +|---|---|---| +| `dependencyId` | string | Managed dependency identity. | +| `activePath` | path/null | First executable or asset selected by the active environment. | +| `sourceClass` | enum | `managed-user-local`, `macports`, `homebrew`, `manual`, `font-registry`, `absent`, `unknown`. | +| `observedVersion` | string/null | Parsed executable version or verified font asset identity. | +| `comparison` | enum | `missing`, `equal`, `older`, `newer`, `unparseable`, `incompatible`. | +| `duplicates` | list | Additional candidate paths or assets; informational only. | + +Validation rules: + +- Competing Homebrew or manual installations are never automatically removed. +- A duplicate candidate must be reported when it affects active compatibility. +- A successful run verifies the active installation after mutation or confirms it was already compatible. + +## MontereyDiagnostic + +The user-facing and evidence-facing result for a blocked, compatible, unsupported, or partial Monterey run. + +| Field | Type | Rules | +|---|---|---| +| `result` | enum | `compatible`, `prerequisite-blocked`, `preflight-blocked`, `target-unsupported`, `interaction-required`, `partial-failure`, `unsupported`. | +| `dependencyId` | string/null | Required for dependency-specific failures. | +| `expected` | string | Expected version, package path, or prerequisite. | +| `observed` | string | Observed version, path, missing state, or failure reason. | +| `target` | MacOSTarget | Exact macOS release category, architecture, role, and package-management path. | +| `nextAction` | string | Safe action the user can perform. | + +Validation rules: + +- `prerequisite-blocked`, `preflight-blocked`, `target-unsupported`, and `interaction-required` happen before + dependency mutation. +- Partial failure reports changed, failed, and pending dependencies plus safe removal guidance. +- Compatible results require every role-applicable dependency to be verified. + +## State Transitions + +```text +detect macOS major version and architecture + -> if macOS 12: select Monterey legacy path + -> if newer macOS: retain existing macOS path + -> filter dependencies by role + -> resolve source selection for each applicable dependency + -> if any selected source requires MacPorts: validate MacPorts prerequisite + -> missing/unusable: PREREQUISITE_BLOCKED, no mutation + -> observe active installations and duplicates + -> preflight selected artifacts/packages + -> any failure: PREFLIGHT_BLOCKED, no mutation + -> apply changes in dependency order + -> verify active result after each change + -> failure: PARTIAL_FAILURE + -> all verified: COMPATIBLE +``` diff --git a/specs/004-macos12-macports-support/plan.md b/specs/004-macos12-macports-support/plan.md new file mode 100644 index 0000000..ffc1f38 --- /dev/null +++ b/specs/004-macos12-macports-support/plan.md @@ -0,0 +1,131 @@ +# Implementation Plan: macOS 12 MacPorts Support + +**Branch**: `004-macos12-macports-support` | **Date**: 2026-08-03 | **Spec**: [spec.md](./spec.md) + +**Input**: Feature specification from `/specs/004-macos12-macports-support/spec.md` + +## Summary + +Add a Monterey-specific macOS dependency path for Mac mini systems that treats Homebrew as unsuitable +for macOS 12 while preserving the current macOS behavior for newer releases. The implementation will +keep checksum-verified official artifacts as the preferred source when they remain compatible on +Monterey, introduce MacPorts-aware target selection and prerequisite diagnostics for legacy macOS, add +MacPorts PATH awareness, extend fixtures for blocked and mixed-manager states, and document real Mac +mini validation without claiming unperformed platform verification. + +## Technical Context + +**Language/Version**: chezmoi templates; POSIX `sh`; YAML dependency data; Markdown documentation; +PowerShell and shell-based policy tests where existing test harnesses require them +**Primary Dependencies**: chezmoi template data/functions, macOS `sw_vers` and `uname`, MacPorts `port`, +existing official upstream release artifacts, POSIX archive/hash utilities, dependency-policy fixtures +**Storage**: committed `.chezmoidata/dependencies.yaml`; generated shell configuration templates; +machine-local dependency state under `${XDG_STATE_HOME:-$HOME/.local/state}`; committed evidence notes +**Testing**: static/template checks on the development host; macOS installer fixtures for Monterey and +newer macOS target selection; existing dependency-policy tests; real-machine validation on a macOS 12 +Monterey Mac mini when available +**Target Platform**: macOS 12 Monterey x86_64 and arm64 Mac mini workstation/server roles, with regression +coverage for existing newer macOS x86_64 and arm64 targets +**Project Type**: cross-platform dotfiles and dependency bootstrap scripts +**Performance Goals**: second apply performs no dependency mutation; prerequisite failure stops before +network or installation work; target detection completes before dependency preflight +**Constraints**: official artifact compatibility remains preferred, MacPorts is a legacy macOS path rather +than the new default for every macOS release, no silent version substitution, no automatic removal of +Homebrew/manual installations, no GUI/font installation for server role, English-only repository content +**Scale/Scope**: existing eight managed dependencies, one additional legacy macOS version category, +two macOS CPU architectures, two roles, existing macOS installer and shared POSIX reconciliation logic + +## Constitution Check + +*GATE: Passed before Phase 0 and re-checked after Phase 1.* + +| Principle | Design evidence | Result | +|---|---|---| +| Cross-Platform Consistency | Monterey uses the same declared dependency policy and compatibility reporting model while adding a legacy macOS target-selection branch. | Pass | +| One-Command, Repeatable Setup | Missing MacPorts prerequisites block before mutation; successful second applies are no-ops; PATH updates must be duplicate-safe. | Pass | +| Native Package Management First | MacPorts becomes the appropriate supported manager for legacy macOS, while official artifacts remain allowed when native packages cannot provide the required compatible version. | Pass | +| Pinned Critical Tool Versions | Monterey must not accept undeclared replacement versions and must verify active versions/assets before reporting compatibility. | Pass | +| Workstation and Server Separation | WezTerm and font handling remain workstation-only on Monterey; server role keeps CLI-only behavior. | Pass | +| English Repository Content | All planned specs, diagnostics, tests, and docs are English. | Pass | +| Platform-Specific Verification | Fixture coverage is required for macOS target-selection behavior; real Mac mini evidence is recorded as verified or explicitly deferred. | Pass | + +Post-design re-check: the research decisions, data model, contracts, and quickstart preserve every gate. +No constitution exception is required. + +## Project Structure + +### Documentation (this feature) + +```text +specs/004-macos12-macports-support/ +|-- plan.md +|-- research.md +|-- data-model.md +|-- quickstart.md +|-- contracts/ +| |-- macos-target-selection.md +| `-- monterey-reconciliation.md +`-- tasks.md # Created later by $speckit-tasks +``` + +### Source Code (repository root) + +```text +.chezmoidata/ +`-- dependencies.yaml # Extend target/source declarations only if Monterey needs source-specific overrides + +.chezmoitemplates/ +|-- dependency-policy-posix.sh.tmpl # Shared preflight/reconciliation support for any MacPorts native-package entries +`-- nushell-config.nu # Add MacPorts executable paths without duplicating entries + +run_onchange_before_10-install-packages-darwin.sh.tmpl + # Detect macOS major version and select legacy/newer macOS package family + +README.md # Document Monterey prerequisite, setup path, and troubleshooting + +tests/dependency-policy/ +|-- test-darwin-dependency-install.sh # Add Monterey and mixed-manager fixtures +|-- README.md # Record fixture coverage and real-machine boundary +`-- evidence/ + `-- macos.md # Record Monterey Mac mini verification or explicit deferral +``` + +**Structure Decision**: Keep the repository's existing dotfiles layout. Add Monterey-aware behavior to the +macOS entrypoint and shared POSIX policy logic instead of creating a separate installer. Use the existing +manifest and fixture directories so Monterey support is reviewed alongside current dependency-policy +coverage. + +## Implementation Phases + +### Phase A - Target selection and source policy + +1. Classify macOS 12 as `darwin-monterey` plus architecture and role while leaving newer macOS targets on + the existing path. +2. Select MacPorts as the legacy macOS package-management family for Monterey prerequisite diagnostics and + any exact native package entries. +3. Continue selecting official artifacts for Monterey when the declared artifact is compatible and + checksum-verifiable. +4. Fail before mutation when MacPorts is required but `port` is missing, not discoverable, or not usable. + +### Phase B - Reconciliation, PATH, and diagnostics + +1. Add MacPorts-aware native package preflight and install behavior only for manifest entries that declare + a MacPorts package source. +2. Add `/opt/local/bin` and `/opt/local/sbin` as macOS candidate paths without creating duplicates or + demoting the managed user-local bin directory. +3. Extend blocked diagnostics with selected package-management path, missing prerequisite, active path, and + next action. +4. Preserve user-owned Homebrew and manual installations: report conflicts, never remove them automatically. + +### Phase C - Fixtures, evidence, and docs + +1. Add macOS fixture scenarios for Monterey Intel/arm64, missing MacPorts, MacPorts not on PATH, + Homebrew-plus-MacPorts conflict, dependency management disabled, workstation, and server roles. +2. Re-run existing dependency-policy checks and confirm newer macOS x86_64/arm64 behavior remains unchanged. +3. Update README setup/troubleshooting sections with Monterey-specific prerequisites and validation steps. +4. Record real Mac mini validation in `tests/dependency-policy/evidence/macos.md`, or explicitly mark it + deferred with commands the user can run on the Monterey machine. + +## Complexity Tracking + +No constitution violations require justification. diff --git a/specs/004-macos12-macports-support/quickstart.md b/specs/004-macos12-macports-support/quickstart.md new file mode 100644 index 0000000..c08f338 --- /dev/null +++ b/specs/004-macos12-macports-support/quickstart.md @@ -0,0 +1,123 @@ +# Quickstart: Validate macOS 12 MacPorts Support + +## Prerequisites + +- Repository checkout with the feature implementation applied. +- For static checks: a development host capable of running the existing dependency-policy test scripts. +- For real-machine validation: a Mac mini running macOS 12 Monterey, with both workstation and server role + scenarios available through fresh or reset chezmoi initialization data. +- MacPorts installed on the real Monterey validation host when testing the compatible path. + +## Static and fixture validation + +### 1. Confirm the active feature directory + +```sh +cat .specify/feature.json +``` + +Expected: the feature directory is `specs/004-macos12-macports-support`. + +### 2. Run dependency-policy manifest checks + +```sh +sh tests/dependency-policy/test-dependency-manifest.sh +``` + +Expected: the manifest is valid, all supported target declarations are complete, and any Monterey-specific +source additions use exact versions. + +### 3. Run macOS installer fixtures + +```sh +sh tests/dependency-policy/test-darwin-dependency-install.sh +``` + +Expected fixture coverage: + +- macOS 12 Intel workstation selects the Monterey legacy path. +- macOS 12 Apple Silicon workstation selects the Monterey legacy path. +- missing `port` produces prerequisite-blocked without mutation when a MacPorts source is required. +- `port` installed outside PATH produces a next-action diagnostic. +- Homebrew and MacPorts both present produces an active-path diagnostic without deleting either source. +- dependency management disabled exits before package-manager checks. +- server role excludes WezTerm and JetBrainsMono Nerd Font. +- newer macOS x86_64 and arm64 fixtures keep the existing macOS path. + +### 4. Run POSIX reconciliation checks + +```sh +sh tests/dependency-policy/test-posix-reconciliation.sh +``` + +Expected: Monterey changes do not regress shared retain, newer-version, preflight, or partial-failure +semantics. + +### 5. Run repository quality checks + +```sh +pwsh -NoLogo -NoProfile -File tests/dependency-policy/Test-DependencyManifest.ps1 +pwsh -NoLogo -NoProfile -File tests/dependency-policy/Test-CIWorkflow.ps1 +``` + +Expected: PowerShell validators continue to pass with the updated support matrix and CI expectations. + +## Real Mac mini validation + +Run these commands on the macOS 12 Monterey Mac mini and record results in +`tests/dependency-policy/evidence/macos.md`. + +### 1. Record host identity + +```sh +sw_vers +uname -m +command -v port || true +port version || true +``` + +Expected: `sw_vers` reports macOS 12.x, `uname -m` is `x86_64` or `arm64`, and `port version` succeeds for +the compatible-path scenario. + +### 2. Validate prerequisite-blocked path + +Temporarily run with `port` unavailable from PATH, then apply the dotfiles with dependency management +enabled. + +Expected: setup stops before dependency mutation and reports the missing MacPorts prerequisite, selected +Monterey package-management path, and next action. + +### 3. Validate workstation compatible path + +With MacPorts available, apply the dotfiles as a workstation. + +Expected: every workstation-applicable managed dependency is installed or verified; WezTerm and +JetBrainsMono Nerd Font are included; the final result is compatible or an explicitly documented retained +unsupported state. + +### 4. Validate idempotency + +Run the same apply command a second time. + +Expected: no compatible managed dependency is reinstalled, no duplicate PATH entries are created, and the +same active versions/assets are reported. + +### 5. Validate server role + +Apply the dotfiles with the server role on the same macOS 12 host or a reset local state. + +Expected: shared CLI tools are handled, while WezTerm and JetBrainsMono Nerd Font are excluded. + +### 6. Validate mixed-manager diagnostics + +If Homebrew is also installed, place a Homebrew-managed executable ahead of the expected active path and +run dependency verification. + +Expected: setup reports the active Homebrew path and selected Monterey package-management path, does not +remove the Homebrew installation, and provides a safe next action. + +## Evidence boundary + +If no macOS 12 Mac mini is available during implementation, the PR must explicitly mark real Monterey +validation as deferred and include the exact commands above for the user to run. Fixture-only evidence must +not be described as full real-platform validation. diff --git a/specs/004-macos12-macports-support/research.md b/specs/004-macos12-macports-support/research.md new file mode 100644 index 0000000..4b429c5 --- /dev/null +++ b/specs/004-macos12-macports-support/research.md @@ -0,0 +1,108 @@ +# Research: macOS 12 MacPorts Support + +## Decision 1: Treat macOS 12 Monterey as a legacy macOS path + +**Decision**: Detect macOS 12 separately from newer macOS and route it through a Monterey-specific legacy +macOS package-management path. + +**Rationale**: Homebrew 4.4.0 announced that macOS Monterey 12 is no longer supported and no longer a CI +target. Homebrew's support-tier documentation also classifies Tier 3 configurations as unsupported, +unstable, lacking CI coverage, and candidates for migration to non-Homebrew tools. This makes Monterey a +bad default for Homebrew-based dependency management even if some commands still work. + +Sources: + +- https://brew.sh/2024/10/01/homebrew-4.4.0/ +- https://docs.brew.sh/Support-Tiers + +**Alternatives considered**: + +- Keep treating all macOS versions the same: rejected because Monterey-specific Homebrew failures would be + surprising and hard to diagnose. +- Mark Monterey unsupported: rejected because the feature goal is to support the user's Mac mini. +- Use MacPorts for all macOS releases: rejected because the feature must preserve newer macOS behavior. + +## Decision 2: Use MacPorts as the legacy macOS manager prerequisite + +**Decision**: For macOS 12, use MacPorts as the declared legacy macOS package-management path whenever a +native package manager is required. + +**Rationale**: MacPorts publishes an installer for macOS 12 Monterey and installs to `/opt/local` by +default. Its guide says the macOS package installer sets up the shell environment and recommends checking +installation with `port version`. This makes it a suitable documented prerequisite for Monterey users. + +Source: + +- https://guide.macports.org/chunked/installing.macports.html + +**Alternatives considered**: + +- Ask users to keep using Homebrew: rejected because Monterey is no longer a suitable supported Homebrew + target. +- Vendor all dependencies into the repository: rejected due to repository size, trust, update, and security + costs. +- Build from source on Monterey: rejected because source builds are slower, harder to reproduce, and contrary + to the existing dependency policy. + +## Decision 3: Keep official artifacts preferred when compatible on Monterey + +**Decision**: Do not replace official artifacts with MacPorts packages merely because the host is Monterey. +Use the existing checksum-verified official artifact strategy when the artifact is compatible and already +covers the Monterey architecture. Add MacPorts native-package entries only for dependencies where the +official artifact is unavailable, incompatible, or otherwise less reliable on Monterey. + +**Rationale**: The current dependency policy already values exact versions and checksum-verified official +artifacts when package managers cannot guarantee the required version. Keeping compatible artifacts avoids +unnecessary package-source churn and limits the MacPorts change to the legacy package-management gap. + +**Alternatives considered**: + +- Convert every macOS dependency to MacPorts: rejected because MacPorts package versions may not match the + declared versions and would increase migration risk. +- Convert every dependency to official artifacts unconditionally: rejected because native package ownership + remains valuable when an exact compatible package is available. + +## Decision 4: Block before mutation when MacPorts is required but unavailable + +**Decision**: If a Monterey run requires MacPorts and `port` is missing, not discoverable, or unusable, the +installer reports `prerequisite-blocked` or the existing nearest blocked result before downloads, installs, +state writes, or PATH mutation. + +**Rationale**: The specification requires prerequisite failures to make no managed dependency changes. Early +blocking keeps the setup safe on machines with partial Homebrew/MacPorts/manual installations. + +**Alternatives considered**: + +- Attempt to install MacPorts automatically: rejected because installing a system package manager requires + user trust, privileges, and Xcode Command Line Tools state that should be documented prerequisites. +- Fall back to Homebrew when MacPorts is missing: rejected because that reintroduces unsupported Homebrew + behavior on Monterey. + +## Decision 5: Add MacPorts paths as candidate paths without changing ownership semantics + +**Decision**: Add `/opt/local/bin` and `/opt/local/sbin` to macOS shell candidate paths, while keeping the +managed user-local bin directory first and avoiding duplicate entries. + +**Rationale**: MacPorts defaults to `/opt/local`, and users need the `port` command and MacPorts-provided +executables discoverable in interactive shells. Keeping `$HOME/.local/bin` first preserves the existing +managed-artifact acceptance path. + +**Alternatives considered**: + +- Put `/opt/local/bin` ahead of `$HOME/.local/bin`: rejected because it could shadow managed official + artifacts and change active-version verification. +- Do not add MacPorts paths: rejected because MacPorts installed by package may not be discoverable in every + shell launched after chezmoi renders shared configuration. + +## Decision 6: Verify newer macOS remains unchanged through fixtures + +**Decision**: Add regression fixtures that render newer macOS x86_64 and arm64 profiles and assert they do +not enter the Monterey-specific path. + +**Rationale**: The constitution requires platform-specific verification and the spec requires Monterey +support not to regress newer macOS behavior. + +**Alternatives considered**: + +- Test only Monterey fixtures: rejected because the primary risk of legacy branching is accidental behavior + changes for existing macOS targets. diff --git a/specs/004-macos12-macports-support/spec.md b/specs/004-macos12-macports-support/spec.md new file mode 100644 index 0000000..03c13b9 --- /dev/null +++ b/specs/004-macos12-macports-support/spec.md @@ -0,0 +1,113 @@ +# Feature Specification: macOS 12 MacPorts Support + +**Feature Branch**: `004-macos12-macports-support` + +**Created**: 2026-08-03 + +**Status**: Draft + +**Input**: User description: "让我的 Mac mini running macOS 12 Monterey also use this terminal workspace; Homebrew is no longer a suitable supported package manager for that legacy macOS version, so use MacPorts where appropriate." + +## User Scenarios & Testing *(mandatory)* + +### User Story 1 - Bootstrap a Monterey Mac mini (Priority: P1) + +As a Mac mini owner running macOS 12 Monterey, I want dependency setup to recognize my system as a supported legacy macOS workstation and guide me through using a suitable package manager so I can install the shared terminal workspace without relying on unsupported Homebrew behavior. + +**Why this priority**: The feature exists to make the user's actual Mac mini a first-class supported target instead of leaving it blocked by Homebrew's legacy macOS support boundary. + +**Independent Test**: Can be fully tested by running the documented bootstrap and dependency setup flow on a macOS 12 Monterey Mac mini configured as a workstation and confirming it reaches a declared compatibility result with clear package-manager diagnostics. + +**Acceptance Scenarios**: + +1. **Given** a macOS 12 Monterey Mac mini workstation with dependency management enabled and the appropriate legacy macOS package manager available, **When** the user applies the dotfiles, **Then** setup installs or verifies every workstation-applicable managed dependency and reports the declared result for Monterey. +2. **Given** a macOS 12 Monterey Mac mini workstation without the required legacy package manager available, **When** dependency setup starts, **Then** setup stops before changing managed dependencies and tells the user which prerequisite is missing and what action to take next. +3. **Given** a macOS 12 Monterey Mac mini workstation where a managed dependency is already present at the declared compatible version, **When** setup runs again, **Then** setup leaves the dependency unchanged and reports it as compatible. + +--- + +### User Story 2 - Preserve modern macOS behavior (Priority: P2) + +As a user of newer macOS machines, I want the existing macOS setup behavior to remain stable so that adding Monterey support does not regress Apple Silicon or newer Intel macOS workstations. + +**Why this priority**: Legacy macOS support must not destabilize already supported macOS targets or change their package source unexpectedly. + +**Independent Test**: Can be tested by rendering or running the dependency setup flow for newer macOS x86_64 and arm64 workstation profiles and confirming they retain their declared package-source behavior and compatibility reporting. + +**Acceptance Scenarios**: + +1. **Given** a supported newer macOS workstation, **When** dependency setup runs, **Then** it continues using the declared package source for that newer macOS target and does not switch to the Monterey-specific path. +2. **Given** a newer macOS workstation with dependency management disabled, **When** setup runs, **Then** shared configuration remains managed while dependency installation remains skipped. + +--- + +### User Story 3 - Diagnose mixed package-manager environments (Priority: P3) + +As a user who may have Homebrew, MacPorts, and manually installed binaries on the same Mac, I want setup to identify which executable is active so I can fix PATH conflicts without accidental duplicate or shadowed installations. + +**Why this priority**: Legacy macOS users often accumulate multiple package managers over time; the feature must keep setup explainable and safe. + +**Independent Test**: Can be tested by preparing a Monterey environment with conflicting executable locations and confirming setup reports the active path, expected source, and safe next action without deleting unrelated user-managed software. + +**Acceptance Scenarios**: + +1. **Given** a Monterey Mac with multiple installations of the same managed tool, **When** setup verifies the active environment, **Then** it reports the active executable path and whether it matches the declared compatible dependency. +2. **Given** a conflicting user-managed installation outside the managed location, **When** setup detects it, **Then** setup provides guidance without removing or overwriting unrelated user-owned software. + +--- + +### Edge Cases + +- The machine reports macOS 12 Monterey but uses either Intel or Apple Silicon hardware. +- The required legacy package manager is installed but not discoverable on the user's active PATH. +- Homebrew and MacPorts are both installed, and the active executable comes from the non-selected package manager. +- A declared official artifact is unavailable, fails integrity verification, or is incompatible with macOS 12. +- A package-manager package exists but does not provide the declared compatible version. +- The user applies a server role on macOS 12; workstation-only GUI terminal and font dependencies must remain excluded. +- Dependency management is disabled; shared configuration must still render without attempting package-manager operations. + +## Requirements *(mandatory)* + +### Functional Requirements + +- **FR-001**: The system MUST recognize macOS 12 Monterey as an explicitly handled legacy macOS target for both Intel and Apple Silicon Mac mini hardware. +- **FR-002**: The system MUST select a package-management path for macOS 12 that does not depend on unsupported Homebrew behavior. +- **FR-003**: The system MUST document any manual prerequisite required before dependency setup can proceed on macOS 12 Monterey. +- **FR-004**: The system MUST stop before making dependency changes when the required Monterey prerequisite is absent, unavailable, or not discoverable. +- **FR-005**: The system MUST keep existing newer macOS behavior separate from the Monterey-specific path unless a user explicitly chooses otherwise. +- **FR-006**: The system MUST preserve the existing workstation/server role split on macOS 12, including excluding GUI terminals and fonts from server role setup. +- **FR-007**: The system MUST verify the active installed version or asset for every managed dependency applicable to macOS 12 before reporting compatibility. +- **FR-008**: The system MUST report actionable diagnostics that identify the dependency, expected version, observed version or absence, active path when available, selected package-management path, and next action whenever setup is blocked. +- **FR-009**: The system MUST avoid deleting or overwriting user-managed installations outside explicitly managed locations. +- **FR-010**: The system MUST remain idempotent: repeated successful setup on the same Monterey Mac mini MUST not reinstall compatible dependencies or duplicate PATH entries. +- **FR-011**: The system MUST not silently substitute a different dependency version when the declared compatible version is unavailable on Monterey. +- **FR-012**: The system MUST provide maintainer-facing verification evidence or manual test instructions for macOS 12 Monterey, covering both successful setup and blocked prerequisite scenarios. +- **FR-013**: The system MUST update user documentation so Monterey users know when to use the legacy macOS path and how it differs from newer macOS setup. +- **FR-014**: The system MUST retain English-only repository content for all committed documentation, script output, configuration comments, and test evidence. + +### Key Entities + +- **macOS Target**: A supported macOS operating-system version category, CPU architecture, and machine role used to decide dependency applicability and compatibility reporting. +- **Package Management Path**: The declared source family used for setup on a macOS target, including its prerequisite state and user-facing diagnostics. +- **Managed Dependency**: A tool or asset controlled by this repository's dependency policy, with declared version, role applicability, verification method, and source strategy. +- **Active Installation**: The executable or asset currently discovered by the user's environment and used as the acceptance source for compatibility checks. +- **Prerequisite Diagnostic**: A blocking message that explains what is missing or unsupported before dependency mutation begins. + +## Success Criteria *(mandatory)* + +### Measurable Outcomes + +- **SC-001**: A macOS 12 Monterey Mac mini user can reach either a compatible setup result or a prerequisite-blocked result with a specific next action in one documented apply attempt. +- **SC-002**: Re-running setup after a successful Monterey installation reports no required dependency changes for already compatible managed dependencies. +- **SC-003**: 100% of Monterey blocked-prerequisite cases identify the missing prerequisite and make no managed dependency changes. +- **SC-004**: 100% of managed dependencies applicable to Monterey report their expected version and observed compatibility state in setup output or recorded evidence. +- **SC-005**: Existing newer macOS workstation checks continue to report the same package-source category and role applicability as before the feature. +- **SC-006**: Documentation includes a Monterey-specific setup path, prerequisite list, troubleshooting guidance, and validation instructions before the feature is considered ready. + +## Assumptions + +- The primary user is a Mac mini owner running macOS 12 Monterey who wants the same terminal workspace experience as newer macOS, Windows, and Linux users. +- macOS 12 Monterey should be treated as a legacy macOS support path rather than as the default behavior for all macOS releases. +- A legacy macOS package manager is acceptable as a manual prerequisite when it is documented before commands that depend on it. +- Existing official prebuilt artifact usage remains acceptable on Monterey when the artifact is compatible, checksum-verifiable, and declared in the dependency policy. +- The feature focuses on this repository's managed terminal workspace dependencies and does not add management for unrelated system tools, secrets, or user-specific configuration. diff --git a/specs/004-macos12-macports-support/tasks.md b/specs/004-macos12-macports-support/tasks.md new file mode 100644 index 0000000..86be3c4 --- /dev/null +++ b/specs/004-macos12-macports-support/tasks.md @@ -0,0 +1,240 @@ +# Tasks: macOS 12 MacPorts Support + +**Input**: Design documents from `/specs/004-macos12-macports-support/` + +**Prerequisites**: plan.md, spec.md, research.md, data-model.md, contracts/, quickstart.md + +**Tests**: Tests are included because the specification requires fixture coverage, static checks, and real Mac mini validation evidence. + +**Organization**: Tasks are grouped by user story to enable independent implementation and testing of each story. + +## Format: `[ID] [P?] [Story] Description` + +- **[P]**: Can run in parallel (different files, no dependencies) +- **[Story]**: Which user story this task belongs to (US1, US2, US3) +- Include exact file paths in descriptions + +## Path Conventions + +- Repository-root dotfiles project with chezmoi templates, shell templates, Markdown documentation, and dependency-policy tests. +- Runtime entrypoints live at repository root and `.chezmoitemplates/`. +- Policy fixtures and evidence live under `tests/dependency-policy/`. + +## Phase 1: Setup (Shared Infrastructure) + +**Purpose**: Inspect the current macOS dependency implementation and prepare the shared test/documentation surfaces. + +- [ ] T001 Inspect current macOS dependency flow in `run_onchange_before_10-install-packages-darwin.sh.tmpl` +- [ ] T002 Inspect shared POSIX reconciliation behavior in `.chezmoitemplates/dependency-policy-posix.sh.tmpl` +- [ ] T003 Inspect existing shell PATH behavior in `.chezmoitemplates/nushell-config.nu` +- [ ] T004 [P] Inspect current dependency manifest target declarations in `.chezmoidata/dependencies.yaml` +- [ ] T005 [P] Inspect existing macOS fixture contract in `tests/dependency-policy/test-darwin-dependency-install.sh` +- [ ] T006 [P] Inspect current macOS evidence notes in `tests/dependency-policy/evidence/macos.md` + +--- + +## Phase 2: Foundational (Blocking Prerequisites) + +**Purpose**: Add shared target-selection, source-selection, and prerequisite semantics that all user stories depend on. + +**⚠️ CRITICAL**: No user story work can begin until this phase is complete. + +- [ ] T007 Define macOS major-version detection and Monterey classification in `run_onchange_before_10-install-packages-darwin.sh.tmpl` +- [ ] T008 Define Monterey package-family selection and newer-macOS preservation in `run_onchange_before_10-install-packages-darwin.sh.tmpl` +- [ ] T009 Add MacPorts prerequisite detection helpers for `port` presence, path, and version in `run_onchange_before_10-install-packages-darwin.sh.tmpl` +- [ ] T010 Extend selected-target diagnostics with macOS release category and package-management path in `run_onchange_before_10-install-packages-darwin.sh.tmpl` +- [ ] T011 Extend native-package preflight to recognize MacPorts package declarations without affecting existing apk behavior in `.chezmoitemplates/dependency-policy-posix.sh.tmpl` +- [ ] T012 Extend native-package installation dispatch for MacPorts declarations without affecting existing apk behavior in `.chezmoitemplates/dependency-policy-posix.sh.tmpl` +- [ ] T013 Add MacPorts source classification for active executable paths under `/opt/local` in `.chezmoitemplates/dependency-policy-posix.sh.tmpl` +- [ ] T014 Add duplicate-safe MacPorts candidate paths `/opt/local/bin` and `/opt/local/sbin` in `.chezmoitemplates/nushell-config.nu` +- [ ] T015 Update dependency-policy fixture vocabulary for Monterey, MacPorts, and prerequisite-blocked states in `tests/dependency-policy/test-darwin-dependency-install.sh` + +**Checkpoint**: Monterey target selection, MacPorts prerequisites, and shared source vocabulary are ready for story implementation. + +--- + +## Phase 3: User Story 1 - Bootstrap a Monterey Mac mini (Priority: P1) 🎯 MVP + +**Goal**: A macOS 12 Monterey Mac mini can use the documented dependency setup path and either reach compatibility or stop before mutation with a clear MacPorts prerequisite diagnostic. + +**Independent Test**: Run the Monterey workstation fixture and the real-machine prerequisite/compatible-path commands from `specs/004-macos12-macports-support/quickstart.md`. + +### Tests for User Story 1 + +- [ ] T016 [P] [US1] Add macOS 12 Intel workstation target-selection fixture in `tests/dependency-policy/test-darwin-dependency-install.sh` +- [ ] T017 [P] [US1] Add macOS 12 Apple Silicon workstation target-selection fixture in `tests/dependency-policy/test-darwin-dependency-install.sh` +- [ ] T018 [P] [US1] Add missing-MacPorts prerequisite-blocked fixture in `tests/dependency-policy/test-darwin-dependency-install.sh` +- [ ] T019 [P] [US1] Add MacPorts-not-on-PATH prerequisite diagnostic fixture in `tests/dependency-policy/test-darwin-dependency-install.sh` + +### Implementation for User Story 1 + +- [ ] T020 [US1] Implement Monterey target key and package-family assignment in `run_onchange_before_10-install-packages-darwin.sh.tmpl` +- [ ] T021 [US1] Implement MacPorts prerequisite-blocked behavior before dependency preflight in `run_onchange_before_10-install-packages-darwin.sh.tmpl` +- [ ] T022 [US1] Implement Monterey official-artifact source preservation for compatible declared artifacts in `.chezmoitemplates/dependency-policy-posix.sh.tmpl` +- [ ] T023 [US1] Implement MacPorts native-package availability checks for exact declared packages in `.chezmoitemplates/dependency-policy-posix.sh.tmpl` +- [ ] T024 [US1] Update Monterey setup and prerequisite documentation in `README.md` +- [ ] T025 [US1] Record Monterey prerequisite and compatible-path validation instructions in `tests/dependency-policy/evidence/macos.md` +- [ ] T026 [US1] Run and record the User Story 1 fixture result in `tests/dependency-policy/README.md` + +**Checkpoint**: User Story 1 is fully functional and testable independently as the MVP. + +--- + +## Phase 4: User Story 2 - Preserve modern macOS behavior (Priority: P2) + +**Goal**: Existing newer macOS x86_64 and arm64 behavior remains unchanged while Monterey uses its legacy path. + +**Independent Test**: Run newer macOS fixture scenarios and confirm they do not enter Monterey-specific target selection or MacPorts prerequisite checks. + +### Tests for User Story 2 + +- [ ] T027 [P] [US2] Add newer macOS x86_64 regression fixture in `tests/dependency-policy/test-darwin-dependency-install.sh` +- [ ] T028 [P] [US2] Add newer macOS arm64 regression fixture in `tests/dependency-policy/test-darwin-dependency-install.sh` +- [ ] T029 [P] [US2] Add dependency-management-disabled macOS fixture that exits before package-manager checks in `tests/dependency-policy/test-darwin-dependency-install.sh` + +### Implementation for User Story 2 + +- [ ] T030 [US2] Guard Monterey-only logic so newer macOS keeps the existing target path in `run_onchange_before_10-install-packages-darwin.sh.tmpl` +- [ ] T031 [US2] Preserve existing macOS role filtering and official-artifact behavior in `.chezmoitemplates/dependency-policy-posix.sh.tmpl` +- [ ] T032 [US2] Update README compatibility wording for Monterey versus newer macOS behavior in `README.md` +- [ ] T033 [US2] Run and record newer macOS regression fixture results in `tests/dependency-policy/README.md` + +**Checkpoint**: User Stories 1 and 2 both work independently without changing newer macOS behavior. + +--- + +## Phase 5: User Story 3 - Diagnose mixed package-manager environments (Priority: P3) + +**Goal**: Monterey users with Homebrew, MacPorts, and manual binaries receive active-path diagnostics without automatic removal of user-owned installations. + +**Independent Test**: Run mixed-manager fixtures and confirm diagnostics include active path, selected package-management path, expected version/source, and safe next action. + +### Tests for User Story 3 + +- [ ] T034 [P] [US3] Add Homebrew-plus-MacPorts active-path conflict fixture in `tests/dependency-policy/test-darwin-dependency-install.sh` +- [ ] T035 [P] [US3] Add manual-binary duplicate active-path fixture in `tests/dependency-policy/test-darwin-dependency-install.sh` +- [ ] T036 [P] [US3] Add macOS 12 server-role fixture that excludes WezTerm and JetBrainsMono Nerd Font in `tests/dependency-policy/test-darwin-dependency-install.sh` + +### Implementation for User Story 3 + +- [ ] T037 [US3] Implement Homebrew, MacPorts, managed-user-local, manual, absent, and unknown active-source classification in `.chezmoitemplates/dependency-policy-posix.sh.tmpl` +- [ ] T038 [US3] Extend blocked diagnostics with active path and selected package-management path in `.chezmoitemplates/dependency-policy-posix.sh.tmpl` +- [ ] T039 [US3] Ensure competing Homebrew and manual installations are reported but never removed in `.chezmoitemplates/dependency-policy-posix.sh.tmpl` +- [ ] T040 [US3] Update troubleshooting guidance for mixed Homebrew, MacPorts, and manual installations in `README.md` +- [ ] T041 [US3] Record mixed-manager and server-role fixture results in `tests/dependency-policy/README.md` + +**Checkpoint**: All user stories are independently functional and mixed-manager diagnostics are safe. + +--- + +## Phase 6: Polish & Cross-Cutting Concerns + +**Purpose**: Verify the full feature, update evidence boundaries, and prepare implementation for review. + +- [ ] T042 [P] Run `sh tests/dependency-policy/test-darwin-dependency-install.sh` and record results in `tests/dependency-policy/README.md` +- [ ] T043 [P] Run `sh tests/dependency-policy/test-posix-reconciliation.sh` and record results in `tests/dependency-policy/README.md` +- [ ] T044 Run `sh tests/dependency-policy/test-dependency-manifest.sh` with `CHEZMOI` configured and record results in `tests/dependency-policy/README.md` +- [ ] T045 Run PowerShell dependency-policy validators and record results in `tests/dependency-policy/README.md` +- [ ] T046 Verify no unresolved placeholders or clarification markers remain in `specs/004-macos12-macports-support/` +- [ ] T047 Update real Mac mini verified or deferred evidence status in `tests/dependency-policy/evidence/macos.md` +- [ ] T048 Review implementation against constitution gates and record any deferred platform validation in `tests/dependency-policy/README.md` +- [ ] T049 Update `specs/004-macos12-macports-support/quickstart.md` if implemented commands differ from the planned validation flow + +--- + +## Dependencies & Execution Order + +### Phase Dependencies + +- **Setup (Phase 1)**: No dependencies; can start immediately. +- **Foundational (Phase 2)**: Depends on Setup completion; blocks all user stories. +- **User Story 1 (Phase 3)**: Depends on Foundational completion; MVP scope. +- **User Story 2 (Phase 4)**: Depends on Foundational completion; can run after or alongside US1 if file conflicts are coordinated. +- **User Story 3 (Phase 5)**: Depends on Foundational completion; can run after or alongside US1/US2 if file conflicts are coordinated. +- **Polish (Phase 6)**: Depends on all desired user stories being complete. + +### User Story Dependencies + +- **User Story 1 (P1)**: Can start after Foundational; no dependency on US2 or US3. +- **User Story 2 (P2)**: Can start after Foundational; validates newer macOS non-regression independently. +- **User Story 3 (P3)**: Can start after Foundational; depends on shared active-source vocabulary but not on US2. + +### Within Each User Story + +- Fixture tasks should be added before implementation tasks where possible. +- Target selection precedes source selection. +- Prerequisite checks precede dependency preflight. +- Diagnostics are completed before evidence/documentation is marked verified. +- Story checkpoint must pass before claiming that story as complete. + +### Parallel Opportunities + +- T004, T005, and T006 can run in parallel during Setup. +- T016, T017, T018, and T019 can run in parallel after Foundational tasks complete. +- T027, T028, and T029 can run in parallel after Foundational tasks complete. +- T034, T035, and T036 can run in parallel after Foundational tasks complete. +- T042 and T043 can run in parallel during Polish. + +--- + +## Parallel Example: User Story 1 + +```bash +Task: "T016 [US1] Add macOS 12 Intel workstation target-selection fixture in tests/dependency-policy/test-darwin-dependency-install.sh" +Task: "T017 [US1] Add macOS 12 Apple Silicon workstation target-selection fixture in tests/dependency-policy/test-darwin-dependency-install.sh" +Task: "T018 [US1] Add missing-MacPorts prerequisite-blocked fixture in tests/dependency-policy/test-darwin-dependency-install.sh" +Task: "T019 [US1] Add MacPorts-not-on-PATH prerequisite diagnostic fixture in tests/dependency-policy/test-darwin-dependency-install.sh" +``` + +## Parallel Example: User Story 2 + +```bash +Task: "T027 [US2] Add newer macOS x86_64 regression fixture in tests/dependency-policy/test-darwin-dependency-install.sh" +Task: "T028 [US2] Add newer macOS arm64 regression fixture in tests/dependency-policy/test-darwin-dependency-install.sh" +Task: "T029 [US2] Add dependency-management-disabled macOS fixture that exits before package-manager checks in tests/dependency-policy/test-darwin-dependency-install.sh" +``` + +## Parallel Example: User Story 3 + +```bash +Task: "T034 [US3] Add Homebrew-plus-MacPorts active-path conflict fixture in tests/dependency-policy/test-darwin-dependency-install.sh" +Task: "T035 [US3] Add manual-binary duplicate active-path fixture in tests/dependency-policy/test-darwin-dependency-install.sh" +Task: "T036 [US3] Add macOS 12 server-role fixture that excludes WezTerm and JetBrainsMono Nerd Font in tests/dependency-policy/test-darwin-dependency-install.sh" +``` + +--- + +## Implementation Strategy + +### MVP First (User Story 1 Only) + +1. Complete Phase 1: Setup. +2. Complete Phase 2: Foundational. +3. Complete Phase 3: User Story 1. +4. Stop and validate Monterey workstation bootstrap independently. +5. Record real Mac mini validation or explicit deferral before claiming Monterey support. + +### Incremental Delivery + +1. Complete Setup + Foundational so target selection and source semantics are stable. +2. Add User Story 1 and validate Monterey MVP behavior. +3. Add User Story 2 and validate newer macOS behavior has not regressed. +4. Add User Story 3 and validate mixed-manager diagnostics. +5. Complete Polish checks and update evidence. + +### Parallel Team Strategy + +With multiple contributors: + +1. Complete Setup + Foundational together. +2. After Foundational completion, one contributor can implement US1 fixtures/behavior, another can implement US2 regression fixtures/docs, and another can implement US3 mixed-manager diagnostics. +3. Coordinate shared-file edits in `run_onchange_before_10-install-packages-darwin.sh.tmpl`, `.chezmoitemplates/dependency-policy-posix.sh.tmpl`, `README.md`, and `tests/dependency-policy/test-darwin-dependency-install.sh` to avoid conflicting changes. + +--- + +## Notes + +- Every task uses the required checkbox, sequential task ID, optional `[P]`, story label where applicable, and exact file path. +- `[P]` tasks are limited to tasks that can be prepared independently, though edits to the same fixture file should still be merged carefully. +- User Story 1 is the recommended MVP because it makes the Monterey Mac mini path usable or safely blocked. +- Real Mac mini validation must be recorded as verified or deferred; fixture-only validation must not be described as full real-platform validation.