P1: Fix TestFlight deployment — add LendairApp executable target,
use xcodebuild archive/export instead of swift build for IPA
P2: Fix swift-format — use built-in 'swift format lint' (Swift 5.6+)
instead of external 'swift-format' binary
P3: Create missing index.html for Vite build entry point
P3: Update vercel-action from v30 to v25 (better maintained)
The stale-run detector flagged the same Code Reviewer ghost run
(14acabf9, FRE-4695) for the ~11th time. Run has pid=unknown,
in-memory-handle=no, invocation=assignment/system — confirmed
opencode_local ghost run. Documented in Code Reviewer's AGENTS.md
as expected behavior. Root fixes tracked in FRE-4990 and FRE-5042.
- web-ci.yml: Remove web/ path refs (app is at repo root), fix cache paths, update Vercel action to v30
- ios-ci.yml: Fix swift-format tool name, use debug build for PR CI, add TestFlight deployment job, use env var for Xcode path
- Scaffold package.json, tsconfig.json, vite.config.ts for web project at root
FRE-5017: Run 14acabf9 confirmed ghost run (no process, no in-memory handle).
Root cause tracked in FRE-4990 (critical). Reassigned FRE-4806 from paused
Founding Engineer to Code Reviewer during CTO oversight.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Closed FRE-4989 as false positive (same ghost run 14acabf9)
- Ghost run has pid unknown, no in-memory handle per FRE-4966 pattern
- FRE-4990 remains the root fix (server-side ghost-run dedup)
- Existing ghost run record keeps spawning new evaluation issues
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Investigated ghost run da233115: timer/system run with no process ever started
- Code Reviewer agent healthy, run was a false positive from scheduler
- Closed issue with findings
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- iOS: swift lint, build verification, and test on PR
- Web: typecheck, vitest tests, build, and Vercel deployment (ready for web project)
- Package.swift: defines Lendair as buildable Swift package
- Test target: LendairTests with XCTest boilerplate
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Add getUnreadCount() endpoint to NotificationsServiceProtocol
- Add NotificationUnreadCountResponse model
- Add badgeCount and fetchUnreadCount() to NotificationsViewModel
- Update markAsRead/markAllAsRead to decrement badge count
- Create MainTabView with Home, Challenges, Clubs, Notifications tabs
- Add unread badge on notification tab using .badge() modifier
- Support injected ViewModel in NotificationsView for shared state
- Add badge count tests to NotificationServiceTests
- Fetch unread count on app launch and tab switch
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Implement full MVVM stack for two new community features:
Clubs:
- Persistent runner groups with type, privacy, and member management
- Club discovery, creation, join/leave, and invite workflows
- Member roles (Owner, Admin, Member) and capacity limits
Challenges:
- Time-bound competitive goals with progress tracking and leaderboards
- Challenge types: distance, time, frequency, elevation, calories, streak
- Progress submission, participation status, and ranking
Files:
- Models: Club.swift, Challenge.swift
- Services: ClubService.swift, ChallengeService.swift
- ViewModels: ClubViewModel.swift, ChallengeViewModel.swift
- Views: ClubsView.swift, ClubDetailView.swift, ChallengesView.swift, ChallengeDetailView.swift
- Tests: ClubServiceTests.swift, ChallengeServiceTests.swift
- Updated README.md with new feature documentation
- Extract NotificationItem/NotificationType to Models/Notification.swift
- Create NotificationsServiceProtocol with testable service layer
- Implement markAsRead(id:) and markAllAsRead() with HTTP calls
- Add NotificationError enum with localized descriptions
- Update NotificationsViewModel to use protocol-based service
- Add 18 unit tests (12 ViewModel + 6 Model) with mock service
- Update README with architecture documentation
- Create NotificationsView.swift with SwiftUI List and pull-to-refresh
- Create NotificationRowView.swift for individual notification items
- Create NotificationsViewModel.swift with MVVM pattern
- Implement empty state view for no notifications
- Add mark-as-read and mark-all-as-read functionality
- Support notification types: loan approved/rejected, payment received/due, new lender, system updates
- Add toolbar action for marking all notifications as read
- Include README.md with architecture documentation and integration guide
Next: Connect tRPC notifications router for data fetching
Pushed FRE-4639 build warnings fix to gt/master. All iOS audit stabilization issues now live on main branch.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Daily note for 2026-05-03 with scope definition work
- New Lendair project entity in knowledge graph
- Atomic facts from codebase audit
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Reviewed voiceprint service files from FRE-4510 commit. Identified 8 test coverage areas. Code quality good with clean architecture.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Child issue FRE-4542 created for Pop scope definition → Founding Engineer
- Board interaction created asking about Nessa and Lendair future
- 5 archive projects documented
- Awaiting board input to close out remaining decisions
All scripter code has been migrated to ~/code/scripter. This removes
the overlap items (src/, src-tauri/, server/trpc/, marketing/,
docs/, public/, dist/, index.html) with favor-newer policy applied.
All FrenoCorp-unique files archived to scripter/trpc/legacy/ for
reference. Scripter repo's modular tRPC structure supersedes the
flat-router format.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Integrates spamAuditLogger into SMSClassifierService.classify() and
CallAnalysisService.analyzeCall(). Each decision logs:
- Classification type (sms/call), phone hash, decision, confidence
- Feature flags active at time of classification
- Decision rationale (feature list for SMS, reason codes for calls)
Audit entries are queryable via spamAuditLogger.getEntries() with
filters for type, decision, date range, and limit. Summary stats
available via getSummary().
Co-Authored-By: Paperclip <noreply@paperclip.ing>
Add promise-based lazy initialization via ensureInitialized() to deduplicate
concurrent initialize() calls. Concurrent callers now await the same
initialization promise instead of each triggering a separate load.
Co-Authored-By: Paperclip <noreply@paperclip.ing>
- Create voiceprint.feature-flags.ts to re-export checkFlag
- Update voiceprint.config.ts to use checkFlag for all flags
- Update voiceprint.service.ts to import checkFlag
- Ensure voiceprint services respect feature flags