Commit Graph
4 Commits
Author SHA1 Message Date
james.maes afd2bc617e fix(01-CR-01): enforce device-only keychain accessibility + non-sync
Phase 1 REVIEW.md CR-01 (SEC-01 / D-10): `SystemKeychainStore` previously
omitted `kSecAttrAccessible` and `kSecAttrSynchronizable`, so items were
written with the OS default — eligible for iCloud Keychain migration and
Time Machine backup, contradicting the "never leaves this device"
guarantee.

packages/Keychain/Sources/Keychain/SystemKeychainStore.swift:7-40
- Add `kSecAttrAccessibleWhenUnlockedThisDeviceOnly` to every
  SecItemAdd / SecItemUpdate attrs payload.
- Add `kSecAttrSynchronizable = kCFBooleanFalse` to both the query and
  the attrs payload (legacy macOS keychain matches on exact sync value).

packages/Keychain/Tests/KeychainTests/KeychainTests.swift
- Add `test_itemIsNotSynchronizable`: asserts that a query with
  `kSecAttrSynchronizable = true` returns errSecItemNotFound for a
  freshly-written item, and the non-sync query does find it.
- Add `test_sourceAlwaysSetsDeviceOnlyAccessibility`: source-level grep
  gate so a future refactor that drops either attribute fails CI.
  (The legacy file-based macOS keychain does not echo
  `kSecAttrAccessible` back via SecItemCopyMatching, so a runtime
  assertion is not possible without entitlements for the
  data-protection keychain.)
2026-04-23 16:06:50 -05:00
james.maes 206b4aa13f refactor: rename bundle ID com.kingsrook.jarvis → com.koftwentytwo.jarvis
Owner change: project will be owned by KofTwentyTwo. Bundle ID updates
propagate to three ${PRODUCT_BUNDLE_IDENTIFIER} targets, the Keychain
service name (SEC-01 / D-10), the OSLog subsystem identifier, and the
FileRotatingWriter DispatchQueue label. pbxproj regenerated via
xcodegen generate.

Forward-looking planning docs (STATE, REQUIREMENTS, PATTERNS, VALIDATION)
updated to match. Historical records (completed PLAN.md / SUMMARY.md /
RESEARCH.md / audits / CONTEXT / DISCUSSION-LOG) deliberately left as-is
to preserve the audit trail of the original naming decision.

Verified: 49 SPM tests pass (4 Keychain + 15 Config + 13 Logging + 17
Shell), xcodebuild Debug build succeeds with full codesign pipeline.

Decision logged in STATE.md Key Decisions (Locked 2026-04-22).
2026-04-22 17:56:37 -05:00
james.maesandClaude Opus 4.7 dea2d11d71 feat(01-02): build Keychain package (SEC-01)
- Add KeychainItem / KeychainError / KeychainStore / SystemKeychainStore
- SystemKeychainStore wraps Security.framework (SecItemAdd/Copy/Update/Delete)
- KeychainItem.anthropic pinned to (com.kingsrook.jarvis, anthropic) per D-10
- set() is idempotent (SecItemUpdate then SecItemAdd on errSecItemNotFound)
- delete() swallows errSecItemNotFound
- Per-test-random account suffix avoids collision with real user Keychain state
- Deletes Plan 01 placeholder sources/tests

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 12:46:35 -05:00
james.maes d8617ffe01 feat(01-01): add four SPM packages with Swift 6 strict concurrency
- packages/Keychain — zero SPM deps (Security.framework at link time only)
- packages/Logging — depends on apple/swift-log 1.5.3+; library product is
  named JarvisLogging to avoid collision with swift-log's own Logging module
- packages/Config — depends on Keychain + Logging (product JarvisLogging)
- packages/Shell — depends on Config + Logging; links AppKit,
  ServiceManagement, IOKit, Carbon for hotkey/launch-at-login surfaces

Every target (main + test) opts into .swiftLanguageMode(.v6) per D-04 so
data-race errors are compile-time failures, not warnings.

Placeholder sources (one per package) plus one trivial XCTest per package
per D-03 so each package builds standalone and has a passing test. Real
sources land in Plan 02 (Keychain/Config/Logging) and Plan 04 (Shell).

Bus/LLM/MCP/Voice/Memory packages NOT pre-created per D-01 — they arrive
in their owning phases (P2/P4/P5/P6/P7) to keep rebuild scope tight.
2026-04-22 12:21:07 -05:00