swift-architecture-pro — independently scanned and version-tracked by SaferSkills.
SaferSkills independently audited swift-architecture-pro (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.
Structure apps so features are isolated, testable, and easy to reason about.
Trigger: /swift-architecture-pro.
@Observable models.❌ By layer
Views/ Models/ ViewModels/ Services/ // every feature scattered across all four✅ By feature
Features/
Feed/ FeedView.swift FeedModel.swift FeedService.swift
Profile/ ProfileView.swift ProfileModel.swift
Core/ Networking/ Persistence/ DesignSystem/@MainActor @Observable
final class FeedModel {
private(set) var posts: [Post] = []
private let service: FeedServing
init(service: FeedServing) { self.service = service }
func load() async { posts = (try? await service.posts()) ?? [] }
}
struct FeedView: View {
@State private var model: FeedModel
var body: some View {
List(model.posts) { PostRow($0) }
.task { await model.load() }
}
}View has no networking, no business rules — only presentation.
❌ Singleton reached from inside
final class FeedModel {
func load() async { posts = await API.shared.posts() } // untestable
}✅ Protocol injected
protocol FeedServing { func posts() async throws -> [Post] }
final class FeedModel { init(service: FeedServing) { ... } }
// tests inject a fake; app injects the real oneCentralize a typed route; drive NavigationStack from it.
enum Route: Hashable { case detail(Post.ID), settings }
@Observable final class Router { var path: [Route] = [] }
NavigationStack(path: $router.path) {
HomeView()
.navigationDestination(for: Route.self) { route in
switch route { case .detail(let id): DetailView(id: id)
case .settings: SettingsView() }
}
}Don't scatter NavigationLink(destination:) literals across the tree.
View → Model (@Observable) → Service (protocol) → Client (network/db). Dependencies point downward only; lower layers never import UI.
View.Per issue: file:line, the boundary violated, suggested split. Lead with testability blockers (hard-wired singletons, logic in views).
~30 seconds. Free. No account. Every finding cites a rule and a line of evidence.