[2.23.0] Major update to agent-native-architecture skill (#70)
Align skill with canonical Agent-Native Architecture document: ## Core Changes - Restructure SKILL.md with 5 named principles from canonical: - Parity: Agent can do whatever user can do - Granularity: Prefer atomic primitives - Composability: Features are prompts - Emergent Capability: Handle unanticipated requests - Improvement Over Time: Context accumulation - Add "The test" for each principle - Add "Why Now" section (Claude Code origin story) - Update terminology from "prompt-native" to "agent-native" - Add "The Ultimate Test" to success criteria ## New Reference Files - files-universal-interface.md: Why files, organization patterns, context.md pattern, conflict model - from-primitives-to-domain-tools.md: When to add domain tools, graduating to code - agent-execution-patterns.md: Completion signals, partial completion, context limits - product-implications.md: Progressive disclosure, latent demand discovery, approval matrix ## Updated Reference Files - mobile-patterns.md: Add iOS storage architecture (iCloud-first), "needs validation" callouts, on-device vs cloud section - architecture-patterns.md: Update overview to reference 5 principles and cross-link new files ## Anti-Patterns - Add missing anti-patterns: agent as router, build-then-add-agent, request/response thinking, defensive tool design, happy path in code 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-authored-by: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,10 +1,188 @@
|
||||
<overview>
|
||||
Mobile agent-native apps face unique challenges: background execution limits, system permissions, network constraints, and cost sensitivity. This guide covers patterns for building robust agent experiences on iOS and Android.
|
||||
Mobile is a first-class platform for agent-native apps. It has unique constraints and opportunities. This guide covers why mobile matters, iOS storage architecture, checkpoint/resume patterns, and cost-aware design.
|
||||
</overview>
|
||||
|
||||
<why_mobile>
|
||||
## Why Mobile Matters
|
||||
|
||||
Mobile devices offer unique advantages for agent-native apps:
|
||||
|
||||
### A File System
|
||||
Agents can work with files naturally, using the same primitives that work everywhere else. The filesystem is the universal interface.
|
||||
|
||||
### Rich Context
|
||||
A walled garden you get access to. Health data, location, photos, calendars—context that doesn't exist on desktop or web. This enables deeply personalized agent experiences.
|
||||
|
||||
### Local Apps
|
||||
Everyone has their own copy of the app. This opens opportunities that aren't fully realized yet: apps that modify themselves, fork themselves, evolve per-user. App Store policies constrain some of this today, but the foundation is there.
|
||||
|
||||
### Cross-Device Sync
|
||||
If you use the file system with iCloud, all devices share the same file system. The agent's work on one device appears on all devices—without you having to build a server.
|
||||
|
||||
### The Challenge
|
||||
|
||||
**Agents are long-running. Mobile apps are not.**
|
||||
|
||||
An agent might need 30 seconds, 5 minutes, or an hour to complete a task. But iOS will background your app after seconds of inactivity, and may kill it entirely to reclaim memory. The user might switch apps, take a call, or lock their phone mid-task.
|
||||
|
||||
This means mobile agent apps need:
|
||||
- **Checkpointing** — Saving state so work isn't lost
|
||||
- **Resuming** — Picking up where you left off after interruption
|
||||
- **Background execution** — Using the limited time iOS gives you wisely
|
||||
- **On-device vs. cloud decisions** — What runs locally vs. what needs a server
|
||||
</why_mobile>
|
||||
|
||||
<ios_storage>
|
||||
## iOS Storage Architecture
|
||||
|
||||
> **Needs validation:** This is an approach that works well, but better solutions may exist.
|
||||
|
||||
For agent-native iOS apps, use iCloud Drive's Documents folder for your shared workspace. This gives you **free, automatic multi-device sync** without building a sync layer or running a server.
|
||||
|
||||
### Why iCloud Documents?
|
||||
|
||||
| Approach | Cost | Complexity | Offline | Multi-Device |
|
||||
|----------|------|------------|---------|--------------|
|
||||
| Custom backend + sync | $$$ | High | Manual | Yes |
|
||||
| CloudKit database | Free tier limits | Medium | Manual | Yes |
|
||||
| **iCloud Documents** | Free (user's storage) | Low | Automatic | Automatic |
|
||||
|
||||
iCloud Documents:
|
||||
- Uses user's existing iCloud storage (free 5GB, most users have more)
|
||||
- Automatic sync across all user's devices
|
||||
- Works offline, syncs when online
|
||||
- Files visible in Files.app for transparency
|
||||
- No server costs, no sync code to maintain
|
||||
|
||||
### Implementation: iCloud-First with Local Fallback
|
||||
|
||||
```swift
|
||||
// Get the iCloud Documents container
|
||||
func iCloudDocumentsURL() -> URL? {
|
||||
FileManager.default.url(forUbiquityContainerIdentifier: nil)?
|
||||
.appendingPathComponent("Documents")
|
||||
}
|
||||
|
||||
// Your shared workspace lives in iCloud
|
||||
class SharedWorkspace {
|
||||
let rootURL: URL
|
||||
|
||||
init() {
|
||||
// Use iCloud if available, fall back to local
|
||||
if let iCloudURL = iCloudDocumentsURL() {
|
||||
self.rootURL = iCloudURL
|
||||
} else {
|
||||
// Fallback to local Documents (user not signed into iCloud)
|
||||
self.rootURL = FileManager.default.urls(
|
||||
for: .documentDirectory,
|
||||
in: .userDomainMask
|
||||
).first!
|
||||
}
|
||||
}
|
||||
|
||||
// All file operations go through this root
|
||||
func researchPath(for bookId: String) -> URL {
|
||||
rootURL.appendingPathComponent("Research/\(bookId)")
|
||||
}
|
||||
|
||||
func journalPath() -> URL {
|
||||
rootURL.appendingPathComponent("Journal")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Directory Structure in iCloud
|
||||
|
||||
```
|
||||
iCloud Drive/
|
||||
└── YourApp/ # Your app's container
|
||||
└── Documents/ # Visible in Files.app
|
||||
├── Journal/
|
||||
│ ├── user/
|
||||
│ │ └── 2025-01-15.md # Syncs across devices
|
||||
│ └── agent/
|
||||
│ └── 2025-01-15.md # Agent observations sync too
|
||||
├── Research/
|
||||
│ └── {bookId}/
|
||||
│ ├── full_text.txt
|
||||
│ └── sources/
|
||||
├── Chats/
|
||||
│ └── {conversationId}.json
|
||||
└── context.md # Agent's accumulated knowledge
|
||||
```
|
||||
|
||||
### Handling iCloud File States
|
||||
|
||||
iCloud files may not be downloaded locally. Handle this:
|
||||
|
||||
```swift
|
||||
func readFile(at url: URL) throws -> String {
|
||||
// iCloud may create .icloud placeholder files
|
||||
if url.pathExtension == "icloud" {
|
||||
// Trigger download
|
||||
try FileManager.default.startDownloadingUbiquitousItem(at: url)
|
||||
throw FileNotYetAvailableError()
|
||||
}
|
||||
|
||||
return try String(contentsOf: url, encoding: .utf8)
|
||||
}
|
||||
|
||||
// For writes, use coordinated file access
|
||||
func writeFile(_ content: String, to url: URL) throws {
|
||||
let coordinator = NSFileCoordinator()
|
||||
var error: NSError?
|
||||
|
||||
coordinator.coordinate(
|
||||
writingItemAt: url,
|
||||
options: .forReplacing,
|
||||
error: &error
|
||||
) { newURL in
|
||||
try? content.write(to: newURL, atomically: true, encoding: .utf8)
|
||||
}
|
||||
|
||||
if let error = error { throw error }
|
||||
}
|
||||
```
|
||||
|
||||
### What iCloud Enables
|
||||
|
||||
1. **User starts experiment on iPhone** → Agent creates config file
|
||||
2. **User opens app on iPad** → Same experiment visible, no sync code needed
|
||||
3. **Agent logs observation on iPhone** → Syncs to iPad automatically
|
||||
4. **User edits journal on iPad** → iPhone sees the edit
|
||||
|
||||
### Entitlements Required
|
||||
|
||||
Add to your app's entitlements:
|
||||
|
||||
```xml
|
||||
<key>com.apple.developer.icloud-container-identifiers</key>
|
||||
<array>
|
||||
<string>iCloud.com.yourcompany.yourapp</string>
|
||||
</array>
|
||||
<key>com.apple.developer.icloud-services</key>
|
||||
<array>
|
||||
<string>CloudDocuments</string>
|
||||
</array>
|
||||
<key>com.apple.developer.ubiquity-container-identifiers</key>
|
||||
<array>
|
||||
<string>iCloud.com.yourcompany.yourapp</string>
|
||||
</array>
|
||||
```
|
||||
|
||||
### When NOT to Use iCloud Documents
|
||||
|
||||
- **Sensitive data** - Use Keychain or encrypted local storage instead
|
||||
- **High-frequency writes** - iCloud sync has latency; use local + periodic sync
|
||||
- **Large media files** - Consider CloudKit Assets or on-demand resources
|
||||
- **Shared between users** - iCloud Documents is single-user; use CloudKit for sharing
|
||||
</ios_storage>
|
||||
|
||||
<background_execution>
|
||||
## Background Execution & Resumption
|
||||
|
||||
> **Needs validation:** These patterns work but better solutions may exist.
|
||||
|
||||
Mobile apps can be suspended or terminated at any time. Agents must handle this gracefully.
|
||||
|
||||
### The Challenge
|
||||
@@ -623,13 +801,48 @@ class AgentOrchestrator {
|
||||
```
|
||||
</battery_awareness>
|
||||
|
||||
<on_device_vs_cloud>
|
||||
## On-Device vs. Cloud
|
||||
|
||||
Understanding what runs where in a mobile agent-native app:
|
||||
|
||||
| Component | On-Device | Cloud |
|
||||
|-----------|-----------|-------|
|
||||
| Orchestration | ✅ | |
|
||||
| Tool execution | ✅ (file ops, photo access, HealthKit) | |
|
||||
| LLM calls | | ✅ (Anthropic API) |
|
||||
| Checkpoints | ✅ (local files) | Optional via iCloud |
|
||||
| Long-running agents | Limited by iOS | Possible with server |
|
||||
|
||||
### Implications
|
||||
|
||||
**Network required for reasoning:**
|
||||
- The app needs network connectivity for LLM calls
|
||||
- Design tools to degrade gracefully when network is unavailable
|
||||
- Consider offline caching for common queries
|
||||
|
||||
**Data stays local:**
|
||||
- File operations happen on device
|
||||
- Sensitive data never leaves the device unless explicitly synced
|
||||
- Privacy is preserved by default
|
||||
|
||||
**Long-running agents:**
|
||||
For truly long-running agents (hours), consider a server-side orchestrator that can run indefinitely, with the mobile app as a viewer and input mechanism.
|
||||
</on_device_vs_cloud>
|
||||
|
||||
<checklist>
|
||||
## Mobile Agent-Native Checklist
|
||||
|
||||
**iOS Storage:**
|
||||
- [ ] iCloud Documents as primary storage (or conscious alternative)
|
||||
- [ ] Local Documents fallback when iCloud unavailable
|
||||
- [ ] Handle `.icloud` placeholder files (trigger download)
|
||||
- [ ] Use NSFileCoordinator for conflict-safe writes
|
||||
|
||||
**Background Execution:**
|
||||
- [ ] Checkpoint/resume implemented for all agent sessions
|
||||
- [ ] State machine for agent lifecycle (idle, running, backgrounded, etc.)
|
||||
- [ ] Background task extension for critical saves
|
||||
- [ ] Background task extension for critical saves (30 second window)
|
||||
- [ ] User-visible status for backgrounded agents
|
||||
|
||||
**Permissions:**
|
||||
|
||||
Reference in New Issue
Block a user