Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -774,6 +774,7 @@ Completed Milestone 23 by adding the `cloud-inference-skills` child plugin, ship
- [x] Add a `productivity-skills:maintain-project-docs` umbrella workflow after `maintain-project-roadmap` owns small-ticket tracking. It should run the individual docs skills together, enforce the splits between `README.md`, `CONTRIBUTING.md`, `AGENTS.md`, `ACCESSIBILITY.md`, and `ROADMAP.md`, and prevent repeated content from drifting across files.
- [x] Add a first `productivity-skills:design-agent-automation-workflow` planning skill for agent and automation design. It chooses between Codex app automations, `codex exec`, Codex subagents, OpenAI Agents SDK services, LangGraph graphs, Hermes-specific workflows, or no automation yet while delegating stack-specific implementation to the owning plugin.
- [x] Added `productivity-skills:design-agent-eval-workflow` for agent, skill, prompt, and automation eval planning, and skewed automation guidance toward safe full automation with exact escalation gates instead of broad human review.
- [x] Aligned Apple Xcode app guidance around strict MVVM source structure, including view-adjacent view models/controllers, directional `Services/` subdirectories, and `sync-xcode-project-guidance` structure-audit reporting for repeatable downstream drift detection.
- [x] Create a quicker full-auto Socket patch-refresh script for trusted maintainer use. It should bump the shared patch version, validate metadata, satisfy release-ready and subtree gates, push `main` and any required subtree split, tag and publish the GitHub release, verify branch accounting, and run `codex plugin marketplace upgrade socket`.
- [x] Reduce hand-carried patch-release work by capturing commit-bound temporary `CODEX_HOME` marketplace smoke evidence and the final Dependabot alert query, then incorporating both into generated release notes without changing release-ready, subtree, branch-accounting, tag, GitHub release, or final marketplace-upgrade gates.
- [ ] Explore steward-assisted release and worktree orchestration. Start with Socket Steward release preflights and cache-refresh checks, then evaluate whether `swift-steward` or sibling roles should handle read-only release readiness, PR merge sequencing, branch accounting, and parallel worktree status reports while the main thread keeps write, merge, tag, and publish ownership.
Expand Down
72 changes: 46 additions & 26 deletions docs/maintainers/apple-swift-structure-guidance-alignment.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
# Apple Swift Structure Guidance Alignment

This note records the first alignment pass for Gale's preferred Swift and
Apple-platform project structure across Socket's Swift-related skills.
This note records Gale's preferred Swift and Apple-platform project structure
across Socket's Swift-related skills.

## Current Fit

Expand All @@ -15,53 +15,72 @@ The existing guidance is already close to the preferred shape:
- `server-side-swift` owns SwiftPM-first server work and should keep app,
scene, preview, simulator, and Xcode-specific concerns delegated away.

The useful next move is to make the preferred app structure more explicit
inside Apple app guidance, not to rename the whole stack to MVVM-C.
The useful direction is strict Apple-app MVVM for Xcode app projects, while
keeping Swift package and server-side Swift guidance focused on their own
non-app boundaries.

## Preferred Structure

Use a coordinator-shaped, MVVM-C-adjacent model only where it removes real
ownership confusion:
Use strict Apple-app MVVM for Xcode app projects:

- `App` declares app entry, app-wide lifecycle, and the top-level scene list.
- App-wide `@Observable` state lives beside the app entry point in
`WhateverNameApp+ViewModel.swift`, containing
`@Observable final class WhateverNameAppViewModel`.
- `Scene` owns per-window, per-document, or managed scene lifecycle and context.
- Small controller or coordinator objects own navigation, presentation, command,
focus, and workflow state for a view cluster or scene boundary.
- SwiftUI views stay component UI: render state, expose local interactions, and
avoid becoming broad app coordinators.
- View models are typed view-driving state when they clarify a real view or
view-cluster boundary; they are not mandatory wrappers around every model.
- Coordinators are useful for scene, command, workflow, navigation, or
presentation ownership; they should not become a second hidden scene graph.
- View-local state and actions stay in the view where feasible.
- View models are typed view-driving state paired with exactly one owning view
or app entry point.
- SwiftUI view models live beside their matching view as
`SomeKindaView+Model.swift`.
- UIKit and AppKit view-controller support lives beside the matching view as
`SomeKindaView+Controller.swift`.
- Models preserve source-of-truth naming and raw persistence or wire shape until
a real semantic boundary requires mapping.
- `Sources/Models/` owns Core Data persistence models, SwiftData `@Model`
types, app datamodels, DTOs, and shared transfer or persistence shapes.
- `Sources/Services/Consumed`, `Sources/Services/Internal`, and
`Sources/Services/Provided` own services by direction.
- The main app-wide service, when present, lives under
`Sources/Services/Internal/` as `WhateverNameAppService.swift`.
- There is no root `Controllers/` directory in ordinary Xcode app structure.
- Data transformation should prefer small composable functions and functional
pipelines when that keeps flow readable.

## Guidance Changes To Consider
## Implemented Guidance Changes

### `apple-dev-skills:swiftui-app-architecture-workflow`

Add a focused reference or section for "coordinator-shaped SwiftUI" that:
The workflow now treats strict app MVVM as the app-project source layout:

- describes controllers/coordinators as local ownership tools, not mandatory
architecture ceremony
- routes app lifecycle to `App`, scene lifecycle to `Scene`, and component
rendering to `View`
- distinguishes view-driving state from navigation or workflow coordination
- distinguishes view-driving state from services, persistence models, and view
controller support
- warns against environment-object dumping and hidden router state
- keeps native SwiftUI scene actions, focused values, and selection-driven
`NavigationSplitView` as the first choices when they fit

### `apple-dev-skills:sync-xcode-project-guidance`

Update the reusable Xcode project guidance snippet so downstream app repos can
name this preference directly:
The reusable Xcode project guidance now names the structure directly and the
sync runtime emits a `structure_audit` payload for downstream repos:

- small focused controller or coordinator classes are encouraged when they own
a real view cluster, scene, command, or workflow boundary
- broad global coordinators, mandatory view-model wrappers, and duplicate
mapping layers remain anti-patterns
- missing `Sources/Views/Shared`, `Sources/Views/macOS`, `Sources/Views/iOS`,
`Sources/Models`, `Sources/Services/Consumed`, `Sources/Services/Internal`,
or `Sources/Services/Provided`
- legacy `Sources/Controllers`
- unpaired `ViewModel.swift` files
- view model or controller support files outside `Sources/Views`
- missing app-entry view model files
- missing internal app service files when a strict app entry exists

The sync skill still owns downstream repo guidance alignment. Socket Steward and
`productivity-skills:maintain-project-docs` own umbrella Socket docs audits and
proposal reports; they should point at this sync skill when Apple app repo
guidance drift is the concrete finding.

### `apple-dev-skills:sync-swift-package-guidance`

Expand All @@ -74,11 +93,12 @@ AppKit modules.
Keep the shared Swift layer focused on source organization and functional data
flow. It should not learn Apple scene, command, or navigation ownership details.

## Validation For A Future Implementation Slice
## Validation

- Run the Apple Dev child validation added for the touched skill references.
- Run `uv run scripts/validate_socket_metadata.py` from the Socket root after
metadata, marketplace, or exported skill descriptions change.
- Review generated or copied guidance text for consistent vocabulary:
`controller`, `coordinator`, `view-driving state`, `scene`, `view cluster`,
and `component UI`.
`strict Apple-app MVVM`, `view-driving state`, `Services/Consumed`,
`Services/Internal`, `Services/Provided`, `Models`, `Views`, and
`component UI`.
4 changes: 2 additions & 2 deletions docs/maintainers/automation-suitability.md
Original file line number Diff line number Diff line change
Expand Up @@ -151,7 +151,7 @@ as the default Socket maintainer automation runtime.
| `maintain-project-repo` | `codex exec` first; code-owned service for coordinated rollout | It installs managed scripts and CI wrappers. It is deterministic, but the write surface is broad enough that every repo should get a PR. |
| `maintain-project-roadmap` | App check-only or `codex exec`; code-owned service only for planning sync | Roadmaps reflect human priorities. Automate stale-structure fixes, but keep milestone meaning human-reviewed. |
| `sync-swift-package-guidance` | `codex exec` for one repo; code-owned service for SwiftPM fleet sync | It classifies repo shape, writes `AGENTS.md`, and refreshes `maintain-project-repo`. It is suitable for PR-based automation after the Socket-cache companion discovery fix. |
| `sync-xcode-project-guidance` | `codex exec` for one repo; code-owned service for Apple-app fleet sync | It has the same shape as the SwiftPM sync skill but needs more caution around Xcode project state and Apple docs gates. |
| `sync-xcode-project-guidance` | `codex exec` for one repo; code-owned service for Apple-app fleet sync | It has the same shape as the SwiftPM sync skill, reports strict MVVM Xcode app-structure drift through `structure_audit`, and needs more caution around Xcode project state and Apple docs gates. |

## Dedicated Skill Recommendation

Expand All @@ -176,7 +176,7 @@ SDK code generation.

Start with a two-phase system:

1. Use Codex app automations for nightly or weekly inventory reports. These should run check-only audits across a repo list and produce a ranked queue: docs drift, missing maintainer scripts, stale AGENTS guidance, failing issue triage, and Swift/Xcode sync candidates.
1. Use Codex app automations for nightly or weekly inventory reports. These should run check-only audits across a repo list and produce a ranked queue: docs drift, missing maintainer scripts, stale AGENTS guidance, failing issue triage, Swift/Xcode sync candidates, and strict Xcode app-structure drift reported by `sync-xcode-project-guidance`.
2. Use `codex exec` jobs for one-repo PR creation. Each job should receive the repo path, the exact skill, the requested run mode, validation command, and PR expectations. It should never batch unrelated repos into one execution.

Move to a code-owned agent service when the queue itself becomes the product.
Expand Down
2 changes: 2 additions & 0 deletions plugins/apple-dev-skills/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,8 @@ Completed Milestone 53 by adding `devicecheck-app-attest-workflow`, focused refe
- Tightened Xcode project guidance so tracked `.pbxproj` diffs produced by Xcode, XcodeGen, or other project-aware workflows are treated as critical project state that must be reviewed, staged, and committed before push, merge, release, or cleanup.
- Updated standalone install guidance so `apple-dev-skills` defaults to Codex's Git-backed marketplace add/upgrade flow without an explicit ref, documents the optional `socket` marketplace path for Gale's broader plugin set, and keeps manual local clone marketplaces as development and fallback paths.
- Tightened the Swift public API guidance across shared snippets, skill-local snippet copies, and generated `AGENTS.md` templates so public call sites default to streamlined typed APIs, optional defaulted parameters over overloads, request/options structs at four or more public parameters, and enum-backed choice modeling.
- Aligned Xcode app-project guidance around strict Apple-app MVVM source structure: view-local models beside views as `<ViewName>+Model.swift`, UIKit/AppKit controller support beside views as `<ViewName>+Controller.swift`, app-wide `@Observable` state in `<AppName>App+ViewModel.swift`, directional `Services/Consumed`, `Services/Internal`, and `Services/Provided` folders, and no root `Controllers/` directory.
- Added strict app-structure drift reporting to `sync-xcode-project-guidance` and updated the XcodeGen bootstrap scaffold so new SwiftUI app projects start with `Sources/Views/Shared`, `Sources/Views/macOS`, `Sources/Views/iOS`, `Sources/Models`, and directional `Sources/Services` folders.
- Registered Xcode's built-in MCP bridge through the Codex plugin manifest so installed `apple-dev-skills` plugins expose the Xcode-owned MCP path without bundling a separate server package.
- Added an experimental `xcode_lldb` MCP config entry for Xcode 27 beta-era `xcrun lldb-mcp` investigation while keeping the dedicated debugger workflow planned until startup validation succeeds.
- Clarified the Apple `maintain-project-repo` branch-protection contract so generated and synced repos require the `validate` Actions check context instead of the workflow-title display string.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -59,10 +59,13 @@ Use this snippet in repository `AGENTS.md` files when you want baseline standard
## SwiftUI and State Architecture

- Treat SwiftUI views as component UI: keep them small, composable, reusable, and easy to scan from top to bottom.
- Use a strict Apple-app MVVM shape for Xcode app projects: views own their own view-local state and actions where feasible, view models stay paired with their owning app or view, persistence and transfer shapes live in `Models/`, and app-wide services live under `Sources/Services/`.
- Require one SwiftUI `View` component per file, named for that component, with that component's Xcode SwiftUI preview in the same file.
- Do not group multiple SwiftUI view components into one Swift file, even when the views are small, private, related, nested, or currently used only by one parent.
- SwiftUI view models are always per-view, with no exceptions: the model for `<ViewFileName>.swift` must live in `<ViewFileName>+Model.swift` and must not be shared with any other SwiftUI view.
- Do not create shared SwiftUI view-model files, grouped SwiftUI view-model files, or view-cluster models. Split shared state into explicit inputs, bindings, environment values, focused values, SwiftData model objects, or a non-SwiftUI boundary when that boundary is genuinely outside the view layer.
- SwiftUI view models are always per-view, with no exceptions: the model for `<ViewFileName>.swift` must live beside the view in `<ViewFileName>+Model.swift` and must not be shared with any other SwiftUI view.
- Do not create shared SwiftUI view-model files, grouped SwiftUI view-model files, view-cluster models, or unpaired `ViewModel.swift` files. Split shared state into explicit inputs, bindings, environment values, focused values, SwiftData model objects, or a non-SwiftUI boundary when that boundary is genuinely outside the view layer.
- Put app-wide `@Observable` state beside the app entry point: `WhateverNameApp.swift` owns the single app lifecycle entry, and `WhateverNameApp+ViewModel.swift` owns `@Observable final class WhateverNameAppViewModel`.
- Put UIKit and AppKit view-controller support beside the matching view under `Sources/Views/` as `<ViewName>+Controller.swift`. Do not create or preserve a root `Controllers/` directory for ordinary app structure.
- Prefer straight, top-down data flow with state owned at the narrowest view, scene, or app boundary that matches the behavior.
- Do not build monolithic views, monolithic controllers, or broad shared mutable state when a smaller component boundary would be clearer.
- Keep updates to view-driving state minimal and localized.
Expand All @@ -85,6 +88,12 @@ Use this snippet in repository `AGENTS.md` files when you want baseline standard
- Use the standard top-level Xcode app repository layout when creating or normalizing native app repos: `Sources/`, `Tests/`, `Shared/`, `Extensions/`, `Configurations/`, `Scripts/`, and `Packages/`.
- `Sources/` owns the main app target implementation and app-owned resources/support files. `Tests/` owns all test targets. `Shared/` owns reusable source intended to be compiled into the app and extension targets. `Extensions/` owns extension target roots, one folder per extension. `Configurations/` owns `.xcconfig` layers. `Scripts/` owns project-local automation and build helper scripts. `Packages/` owns local Swift packages only when a real package boundary is justified.
- Keep those top-level roots stable. Do not invent parallel names such as `AppSources`, `TestSources`, `Config`, `BuildScripts`, or `LocalPackages` for ordinary Xcode app repos unless the existing repo already has a deliberate, documented convention.
- Inside `Sources/`, use this strict app structure by default: `Views/`, `Models/`, and `Services/`. Do not create a root `Controllers/` directory.
- `Sources/Views/` owns SwiftUI views and UIKit/AppKit view surfaces. Use `Sources/Views/Shared`, `Sources/Views/macOS`, and `Sources/Views/iOS` so shared, macOS-specific, and iOS/iPadOS-specific UI have clear homes.
- View files are named `<ViewName>.swift`. View-local view models are named `<ViewName>+Model.swift`. UIKit and AppKit controller support files are named `<ViewName>+Controller.swift`. Each paired model or controller file lives beside its matching view in `Sources/Views/` or the appropriate platform/shared subdirectory.
- `Sources/Models/` owns Core Data persistence models, SwiftData `@Model` types, app datamodels, DTOs, and transfer or persistence shapes that are shared across the app. Service-private request/response shapes may stay inside the owning service folder only when they are not meaningful outside that integration.
- `Sources/Services/` owns app-wide and boundary-facing services. Use `Consumed/` for external services the app calls, `Internal/` for services owned only by the app, and `Provided/` for services the app exposes to extensions, helpers, plugins, integrations, or other clients.
- When an app has a single main app-wide service, put it under `Sources/Services/Internal/` as `WhateverNameAppService.swift`.
- Use `xcodebuild` for Apple platform integration validation, including scheme, destination or SDK, and configuration-specific build or test runs.
- Keep `xcodebuild` invocations reproducible in automation by passing explicit schemes, destinations or SDKs, and configurations when relevant.
- For Codex GUI worktree-first Xcode repos, use a portable `.codex/environments/*.toml` local environment file when the repo wants shared app setup or action buttons. Start from `apple-dev-skills/templates/codex-local-environments/xcode-project.toml`, keep paths repo-relative, and prefer `-derivedDataPath ./DerivedData` or another ignored repo-local build directory instead of user-global DerivedData.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,12 @@ archiving, AppKit MVC, Observation interop, and mixed AppKit/SwiftUI composition
It is not the Apple-docs router, not the SwiftUI architecture workflow, not the
accessibility workflow, and not the Xcode execution workflow.

For Xcode app source layout, keep UIKit/AppKit controller support view-adjacent:
`Sources/Views/Shared`, `Sources/Views/macOS`, and `Sources/Views/iOS` own view
surfaces, and controller support files are named `<ViewName>+Controller.swift`
beside their matching view. Do not collect ordinary app controller support in a
root `Controllers/` directory.

## When To Use

- Use this skill when the user wants help structuring an AppKit or mixed
Expand Down Expand Up @@ -118,6 +124,8 @@ accessibility workflow, and not the Xcode execution workflow.
- repositories, stores, service layers, mirrored DTOs, view-model cache
layers, or wrapper objects inserted between SwiftData and SwiftUI-owned
screens
- a root `Controllers/` directory used for ordinary view-controller support
instead of `<ViewName>+Controller.swift` beside the matching view
- app-wide runtime work hidden in a view controller
- menu or status-item behavior hidden in a leaf view
- responder-chain actions replaced by a broad command bus without a real need
Expand Down
Loading