Keep using Photos.app like you always do. Attic quietly backs up your originals and edits to an S3 bucket you control. One-way, append-only.
3
fork

Configure Feed

Select the types of activity you want to include in your feed.

Fix modifier order conflict between swiftlint and swiftformat

+6 -6
+1 -1
.swiftlint.yml
··· 19 19 - empty_string 20 20 - first_where 21 21 - last_where 22 - - modifier_order 23 22 - redundant_type_annotation 24 23 - sorted_imports 25 24 - vertical_whitespace_closing_braces 25 + # modifier_order intentionally omitted — swiftformat handles this 26 26 27 27 identifier_name: 28 28 min_length: 1
+1 -1
Sources/AtticCore/AtticConfig.swift
··· 106 106 107 107 // MARK: - Validation 108 108 109 - nonisolated(unsafe) private let bucketPattern = /^[a-z0-9][a-z0-9.\-]{1,61}[a-z0-9]$/ 109 + private nonisolated(unsafe) let bucketPattern = /^[a-z0-9][a-z0-9.\-]{1,61}[a-z0-9]$/ 110 110 111 111 extension AtticConfig { 112 112 /// Validate a raw JSON object into an AtticConfig.
+1 -1
Sources/AtticCore/RebuildManifest.swift
··· 64 64 let backedUpAt: String? 65 65 } 66 66 67 - nonisolated(unsafe) private let checksumValidation = /^sha256:[a-f0-9]+$/ 67 + private nonisolated(unsafe) let checksumValidation = /^sha256:[a-f0-9]+$/ 68 68 69 69 private func isValidChecksum(_ value: String) -> Bool { 70 70 value.wholeMatch(of: checksumValidation) != nil
+3 -3
Sources/AtticCore/S3Paths.swift
··· 4 4 public enum S3Paths { 5 5 // MARK: - Validation patterns 6 6 7 - nonisolated(unsafe) private static let uuidPattern = /^[A-Za-z0-9._\-]+$/ 8 - nonisolated(unsafe) private static let s3KeyPattern = /^[A-Za-z0-9\/._\-]+$/ 9 - nonisolated(unsafe) private static let extPattern = /^[a-z0-9]+$/ 7 + private nonisolated(unsafe) static let uuidPattern = /^[A-Za-z0-9._\-]+$/ 8 + private nonisolated(unsafe) static let s3KeyPattern = /^[A-Za-z0-9\/._\-]+$/ 9 + private nonisolated(unsafe) static let extPattern = /^[a-z0-9]+$/ 10 10 11 11 /// UTI-to-extension lookup table. 12 12 private static let utiMap: [String: String] = [