Appendix R: OPerationsHOS (Shop Manual)
Status: In development. GPL v3. Public repo at github.com/fluhartyml/OPerationsHOS. Distribution-ready binary for iPhone, iPad, and native macOS as of 2026-05-10. Not yet on App Store. OPerationsHOS is an AI proof-of-concept: architecture by ChatGPT (OpenAI), engineered by Claude (Anthropic). Two AI systems, distinct roles. Michael Fluharty is the human operator, decision-maker, and license holder. The split is intentional and load-bearing — no in-place substitutions, no role overlap.
What it is
OPerationsHOS is a personal operations console: a place to record every appliance warranty, home system, project, contact, document, timer, and reminder that a household generates over time. Its central design rule, lifted directly from the 2026 MAY 04 roadmap: one universal record model first, modules later as filtered lenses. Everything in the app is an OperatorItem. There are no per-type detail views, no parallel WarrantyView / ApplianceView / ProjectView code paths — one detail renderer, many record types.
Architecture overview
The project is a SwiftUI app with SwiftData persistence, an App Group widget extension, and platform-tuned shells for iPhone, iPad, and native macOS.
File roles, by category:
- App entry:
OPerationsHOSApp.swift(the@mainscene with the sharedModelContainer),ContentView.swift. - Shell views:
AppShellView.swift(the routing entry that picks the per-platform shell),RootTabView.swift(iPhone),IPadShellView.swift(iPad three-column),MacShellView.swift(native macOS three-column with Cmd-N keyboard shortcut). - Tab / module views:
DashboardView.swift,InboxView.swift,ScheduleView.swift,RemindersView.swift,VaultView.swift,ModuleView.swift,SearchView.swift,SettingsView.swift. - Record editing + detail:
RecordDetailView.swift,RecordEditSheet.swift,OperatorCard.swift. - Data model:
OperatorItem.swift(the universal record),ActivityEvent.swift(timeline entries),Attachment.swift(file references). - Store:
OperatorStore.swift(the@Observablefacade aroundModelContext). - Services:
AIService.swift(Anthropic Messages API client),AlarmKitManager.swift(iOS AlarmKit wrapper),EventKitStore.swift(Calendar / Reminders integration),KeychainStorage.swift(secret storage). - Widget bridge:
WidgetSnapshotPublisher.swift(writes JSON to the App Group container on every store refresh). - Theme + helpers:
AppTheme.swift,PersonPickerView.swift,TimerSectionView.swift,SampleData.swift. - Export:
ExportSheet.swift(UI),ExportFormatter.swift(Markdown / PDF / CSV / JSON / ZIP). - About + notes:
AboutView.swift,DeveloperNotes.swift(the full 2026 MAY 04 roadmap as a comment block, with current phase status).
The widget extension lives in OPerationsHOSWidgets/ as a sibling target, embedded into the host app's bundle on iOS only (the embed reference carries platformFilter = ios in the .pbxproj so native macOS builds skip the iOS-shaped widget).
The universal record model
Every record is a single OperatorItem:
@Model
final class OperatorItem {
var id: UUID
var title: String
var subtitle: String
var body: String
var type: ItemType
var status: ItemStatus
var priority: ItemPriority
var createdDate: Date
var updatedDate: Date
var dueDate: Date?
var pinned: Bool
var archived: Bool
var tags: [String]
var relatedSystem: String?
var source: String?
// Relationships
@Relationship(deleteRule: .cascade) var activity: [ActivityEvent]
@Relationship(deleteRule: .cascade) var attachments: [Attachment]
}
The three nested enums — ItemType, ItemStatus, ItemPriority — live in the same file:
ItemType—note,task,document,warranty,appliance,homeSystem,maintenance,project,timer,media,property,person,secureNote.ItemStatus—open,active,waiting,scheduled,complete,archived.ItemPriority— the priority enum used by the dashboard's Today section ordering.
All three are String-backed, Codable, and CaseIterable so they can drive both SwiftData persistence and SwiftUI Picker menus.
Activity events
ActivityEvent is the per-item timeline. Every record gets a list of events (noteAdded, statusChanged, attachmentAdded, etc.). The relationship from OperatorItem deletes events along with the parent record. The ActivityKind enum lists the event categories; the text property stores the human-readable summary.
Attachments
Attachment is a file reference, not the file itself. The AttachmentStorage enum distinguishes .inSandbox (URL inside the app's sandbox) from .iCloudDocument (URL inside the user's iCloud Drive). The AttachmentKind enum tags content type (pdf, image, photo, etc.) for filtering and icon selection. Large files never end up inside the SwiftData store — per the roadmap rule, attachments store file references only.
The store
OperatorStore is the @Observable facade between SwiftUI views and SwiftData. Views never touch ModelContext directly; they go through the store. Reasons:
- Single mutation surface. Adding, updating, deleting, pinning, archiving all happen through store methods. View code stays declarative.
- Side-effect dispatch. Every store mutation can trigger an
ActivityEventappend, anEventKitStoresync, and aWidgetSnapshotPublisherrefresh in one place rather than across every call site. - Testability. A protocol-shaped store could later have an in-memory variant for unit tests — not built yet, but the seam is there.
The store is created once at the app entry in AppShellInner.init from the environment's ModelContext, then passed down to every view that needs it.
Platform shell routing
AppShellView picks the shell based on the runtime platform:
var body: some View {
#if os(macOS)
MacShellView(store: store)
#else
if horizontalSizeClass == .regular {
IPadShellView(store: store)
} else {
RootTabView(store: store)
}
#endif
}
Three shells, three patterns:
RootTabView(iPhone) —TabViewwith.tabViewStyle(.sidebarAdaptable). Each tab wraps its module view in aNavigationStackwith aUUIDnavigation destination that pushesRecordDetailView.IPadShellView(iPad regular width) — three-columnNavigationSplitView: tab sidebar → selected module view →RecordDetailView. NavigationLink pushes onto a state-bound path that.onChangeintercepts and routes to the detail column.MacShellView(native macOS) — same three-column pattern as iPad with Mac-tuned sidebar widths (.navigationSplitViewColumnWidth(min: 200, ideal: 220, max: 280)) and a Cmd-N keyboard shortcut on the toolbar's New Record button.
Tab structure (locked)
The 11 tabs the user sees, in sidebar order:
| # | Tab | Role |
|---|---|---|
| 1 | Dashboard | Today / Pinned / Home Systems / Upcoming / Recently Updated / Projects sections |
| 2 | Inbox | Unfiled / orphan records |
| 3 | Schedule | Calendar-native agenda, EventKit-backed |
| 4 | Reminders | Reminders.app-native, EventKit two-way sync |
| 5 | Systems | Filtered: .homeSystem + .appliance |
| 6 | Maintenance | Filtered: .maintenance |
| 7 | Projects | Filtered: .project |
| 8 | People | Filtered: .person |
| 9 | Timers | Filtered: .timer |
| 10 | Property | Filtered: .property |
| 11 | Vault | Biometrically gated — Media + Secure Notes |
Search and Settings are sibling sidebar entries on iPad / Mac; on iPhone they sit at the end of the TabView.
Service layer
AIService
Anthropic Messages API client. Three actions: summarize(_:), extractDates(from:), suggestCategory(for:). Each builds a system prompt + user prompt, posts to https://api.anthropic.com/v1/messages with the user's API key from the Keychain (KeychainKey.anthropicAPIKey), and returns the parsed text on success or nil with lastError set on failure. Model: claude-haiku-4-5-20251001. maxTokens: 1024. Wired into RecordDetailView at lines 24, 504, 506, 508.
AlarmKitManager
Wrapper around AlarmManager.shared for timer-record integration. iOS / iPadOS / Mac Catalyst only. Guarded with #if canImport(AlarmKit) at the import and at the extension AlarmButton declaration. On native macOS the manager is a stub that returns "AlarmKit is not available on this platform" errors. See Appendix C's "Platform availability and the Mac build" section for the full pattern.
EventKitStore
Calendar and Reminders integration. Bridges OPerationsHOS scheduled records to the user's system calendar (Schedule tab) and task records to Reminders.app (Reminders tab). Two-way sync: changes in either direction reflect in both. Asks for permission via EKEventStore.requestFullAccessToEvents() and the corresponding Reminders permission at first use.
KeychainStorage
An enum KeychainStorage with static read / write / delete methods keyed by KeychainKey (an enum of typed key names). The only key currently in use is .anthropicAPIKey. Generic enough to add more secrets later without expanding the storage surface.
Widget bridge
The widget extension can't share SwiftData with the host app directly. The bridge: WidgetSnapshotPublisher writes a JSON snapshot of the dashboard-relevant records to the App Group container (group.com.ChatGPT.OPerationsHOS) on every store refresh, then calls WidgetCenter.shared.reloadAllTimelines(). The widget reads the JSON, not the SwiftData store. One-way: the widget never writes back. Sandboxing remains intact — the host app holds the SwiftData store; the widget holds a read-only mirror.
Export pipeline
ExportSheet presents a format picker; ExportFormat enumerates the supported outputs (.markdown, .pdf, .csv, .json, .zipWithAttachments); ExportFormatter does the work. Default export scope is "all records" but the formatter accepts a filter predicate for "Home Sale Prep Report," "HVAC History," "Appliance Warranty Packet," and similar packaged reports the user-facing menu lists.
Build + deployment
- Bundle ID:
com.ChatGPT.OPerationsHOS(named for the architecture system, not the engineer). - Supported platforms:
iphoneos iphonesimulator macosx xros xrsimulator— native iPhone, iPad, Mac, and visionOS. Mac Catalyst path inherits the iOS SDK; native macOS uses the macOS SDK. - Targeted device family:
"1,2,7"on the app target (iPhone + iPad + Vision Pro),"1,2"on the widget extension (iPhone + iPad only). - Minimum target: iOS / iPadOS / macOS 17+ per the roadmap.
- CloudKit: wired in the
ModelConfigurationwithcloudKitDatabase: .automatic. Records sync via the user's iCloud automatically.
Known gotchas
- AlarmKit + native macOS. AlarmKit isn't in the macOS SDK. Every reference needs
#if canImport(AlarmKit), and theextension AlarmButtonblock needs the guard at the declaration level (not just the body). See Appendix C. - iOS-only UIKit-derived modifiers.
Color(.systemBackground),.listStyle(.insetGrouped), and.searchable(.., placement: .navigationBarDrawer)all fail on native macOS. Use.background(.background)(SwiftUI semantic),#if os(iOS)guards on the iOS-only styles, and the default.searchableplacement on macOS. - Widget embed on Mac. The widget target is iOS-only. The macOS build fails to embed it unless the embed reference in the
.pbxprojcarriesplatformFilter = ios. See Book 13's "Cross-Platform" section for the exact.pbxprojchange. - Inkwell as a stale name. Early development referred to the iPad reader app as "Inkwell" (Claude's slang). The real project name is "Claudes X26 Swift6 Bible." Both source comments and book passages have been updated; any remaining "Inkwell" reference in this app's vicinity is a bug.
Roadmap status (2026 MAY 04 roadmap)
| Phase | Topic | Status |
|---|---|---|
| 0 | Project setup | Complete |
| 1 | Skeleton app | Complete |
| 2 | Universal record model | Complete |
| 3 | Dashboard | Complete |
| 4 | Record detail view | Complete |
| 5 | Editing | Complete |
| 6 | SwiftData persistence | Complete |
| 7 | Modules | Complete |
| 8 | Search | Complete |
| 9 | Attachments | Complete |
| 10 | Activity log | Complete |
| 11 | Dates and reminders | Complete |
| 12 | Timers / workflow | Complete |
| 13 | AI layer | Complete (AIService wired into RecordDetailView) |
| 14 | iCloud sync | Complete (CloudKit automatic on ModelContainer) |
| 15 | iPad layout | Complete 2026-05-10 (IPadShellView) |
| 16 | Mac layout | Complete 2026-05-10 (MacShellView, native macOS build) |
| 17 | Export | Complete (ExportSheet + ExportFormatter) |
Phases 18–24 (widget code, App Group entitlement, WidgetSnapshotPublisher writing JSON, WidgetCenter reload) all shipped before the roadmap-complete date. The roadmap is the source of truth; DeveloperNotes.swift in the project repo carries the full text as a comment block.
Sources
- Project source: github.com/fluhartyml/OPerationsHOS (verified 2026-05-10).
- Roadmap: 2026 MAY 04 OPerationsHOS roadmap, embedded verbatim in
OPerationsHOS/DeveloperNotes.swift(header + comment block). - Cross-platform background: Book 13 ("Cross-Platform — What Doesn't Translate from iOS to Mac"), Appendix C ("Platform availability and the Mac build").