swiftpm-modularization — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited swiftpm-modularization (Agent Skill) and scored it 100/100 (green). The audit ran 55 deterministic rules across Security, Supply Chain, Maintenance, Transparency, and Community; it found 0 high-severity and 0 lower-severity findings. The full rule-by-rule trace and per-finding evidence are below. Free, methodology-open.
Findings & checks · 0 flagged
Every scanned point with the score it earned and what moved between them.
First recorded scan — no prior version to compare against.
The primary manifest — the file an agent reads to learn what this artifact does.
Package.swift.<Project>Kit).Package.swift maintenance cost and CI resolution time.@main, the App structInfo.plist, entitlementshost-driven-xcuitest-e2e. All testable logic is in the Package.Core (pure Swift, no Apple frameworks)
↑
Domain (business logic / state)
↑
Service modules (CloudKit / GameKit / Storage / Telemetry)
↑
UI module (SwiftUI)
↑
App targetCloudKit is imported only in its designated service target.GameKit / StoreKit.<Module>Tests.<Project>KitTesting target imported by multiple test targets.<Project>/
├── App/ # thin shell
│ ├── <Project>App.swift # @main + DI composition root
│ └── (Assets, Info.plist, entitlements)
└── Packages/
└── <Project>Kit/
├── Package.swift
└── Sources/
├── <Core>/ # pure Swift, no Apple frameworks
├── <Domain>/ # domain logic
├── <Storage>/ # service module (CloudKit import restricted here)
├── <Telemetry>/ # Logger / Tracking facade
└── <UI>/ # SwiftUI Views
└── Tests/
└── <Module>Tests/ # one-to-onePackage.resolved, swift package resolve resolves to the newest version each dependency's range allows — it does not consult a sibling app's committed pins. Running it to "materialize" a fresh Package.resolved for a second app silently drifts its pins away from the first app's committed versions.Package.resolved to B and swap only the originHash (obtained from one throwaway resolve on B), preserving the file's JSON formatting; then verify swift build leaves the file byte-identical (no churn). Diff the full pin list against the reference, not just the one dependency a task happened to mention. Optionally run swift package resolve --force-resolved-versions to check the copied pins still satisfy B's manifest — that flag does not update originHash, so it doesn't replace the swap.swift build plus an import-site grep are not sufficient verification for a target/test-directory rename. Non-Swift tooling — CI workflow files, task runners, code-gen scripts — often hard-code the path string, which compiles fine and passes the import grep but breaks at the tooling layer..xcassets inside a package targetswift test does not compile a package target's .xcassets at all — asset-catalog resourcesare silently invisible to the plain SwiftPM test runner.
own LinkAssetCatalog step when the package is consumed from an Xcode project: both produce Assets.car for the same target, giving Multiple commands produce …Assets.car.
/SourcePackages/plugins/ path does not reliably tell youwhether the build is happening under Xcode — don't rely on it to skip the plugin conditionally.
Bundle.module resources that are not .xcassets.swift6-concurrency: Package applies swiftLanguageModes: [.v6] in one place. swift-tools-version: 6.2 is the shared gate for both platforms: [.iOS(.v26), ...] (apple-platform-targets) and swiftSettings: [.defaultIsolation(...)] (swift6-concurrency) — 6.0/6.1 reject both.apple-platform-targets: Package platforms: aligned with App target.swift-testing-baseline: test target framework and location.telemetry-facade-pattern: why Telemetry is a standalone target.references/official-docs.md.~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.