# Swiftblade — Swift Specialist LoRA

Adapter codename: `swiftblade`
Agent: `build-swift`
Base model: Qwen/Qwen3.5-27B

## Objective

Teach the model Swift/Apple-idiomatic code generation aligned with the build-swift
agent's system prompt. The adapter should internalize:

- Swift 6 strict concurrency (`@Sendable`, `sending`, `@MainActor`)
- SwiftUI first, UIKit only when necessary
- `guard` for early exits, proper optional binding
- Value types over reference types where appropriate
- `URLSession` for networking (no Alamofire)
- swift build → swift test verification cycle
- Architecture detection (MVVM, TCA, MV)

## Current Status

build-swift currently runs on `anthropic/claude-sonnet-4-6` as a quality backstop.
The swiftblade adapter is intended as a local replacement, but deployment depends
on evaluation results. If quality is insufficient, keep Claude as primary and
swiftblade as cost-saving alternative for simple tasks.

## Data Sources

### Session extraction (~20–40 examples)

Swift sessions are rare. Classify by:
- File paths: `.swift`, `Package.swift`, `*.xcodeproj`, `project.yml`
- Bash commands: `swift build`, `swift test`, `xcodebuild`, `swift-format`
- Error patterns: swiftc diagnostics, `error:`, `cannot convert`, `protocol conformance`

### Git repo mining (~30–60 examples)

Target repos:
- `madcat-os/madcat-apple` — iOS/macOS app
- Any Swift packages in madcat-os org

Extract patterns:
- SwiftUI view implementations
- `@Observable` / `ObservableObject` view model patterns
- async/await networking with `URLSession`
- Swift Package Manager configuration
- Actor-based state isolation

### Synthetic (~80–150 examples)

Swift is the most synthetic-heavy adapter:
- Swift 6 concurrency: actors, `@Sendable`, `TaskGroup`, structured concurrency
- SwiftUI: `@State`, `@Binding`, `@Environment`, custom modifiers
- Navigation: `NavigationStack`, `NavigationSplitView`, navigation paths
- Data flow: `@Observable` macro (Swift 5.9+), `@Bindable`
- Platform-specific: `#available`, multi-platform targets
- Swift Testing framework (`@Test`, `#expect`, `@Suite`) vs XCTest
- Combine → async/await migration patterns
- Widget/extension development

## Example Format

```json
{
  "messages": [
    {
      "role": "system",
      "content": "<build-swift agent system prompt>"
    },
    {
      "role": "user",
      "content": "Add a settings view with toggle for dark mode and notification preferences"
    },
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "type": "function",
          "function": {
            "name": "glob",
            "arguments": {"pattern": "Sources/**/*.swift"}
          }
        }
      ]
    },
    {
      "role": "tool",
      "content": "<file list showing existing views>"
    },
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "type": "function",
          "function": {
            "name": "read",
            "arguments": {"filePath": "Sources/Views/ContentView.swift"}
          }
        }
      ]
    },
    {
      "role": "tool",
      "content": "<existing SwiftUI view pattern>"
    },
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "type": "function",
          "function": {
            "name": "write",
            "arguments": {
              "filePath": "Sources/Views/SettingsView.swift",
              "content": "import SwiftUI\n\nstruct SettingsView: View {\n    @AppStorage(\"darkMode\") private var darkMode = false\n    ..."
            }
          }
        }
      ]
    },
    {
      "role": "tool",
      "content": "File written"
    },
    {
      "role": "assistant",
      "content": null,
      "tool_calls": [
        {
          "type": "function",
          "function": {
            "name": "bash",
            "arguments": {"command": "swift build 2>&1"}
          }
        }
      ]
    },
    {
      "role": "tool",
      "content": "Build complete!"
    },
    {
      "role": "assistant",
      "content": "SettingsView created. Uses `@AppStorage` for persistence, `Toggle` for dark mode and notifications. Follows existing MVVM pattern. Builds clean."
    }
  ]
}
```

## Evaluation Criteria

1. `swift build` passes with no warnings
2. Swift 6 concurrency: correct `@Sendable`, actor isolation
3. SwiftUI-first (no UIKit unless justified)
4. Proper optional handling (`guard let`, `if let`, no force-unwrap)
5. Value types where appropriate
6. Architecture matches project (MVVM/TCA/MV detection)
7. Tool call sequence: explore → read patterns → implement → build → test

## Training Config Overrides

```python
MAX_SEQ = 8192
LR      = 5e-5
```

## Estimated Size

- 100–200 examples (mostly synthetic)
- ~0.8M tokens
- Training time: ~1 hr on H100
- Adapter size: ~305 MB

## Risk: Quality Gap vs Claude

Claude Sonnet excels at Swift due to Apple's partnership data. Swiftblade on
Qwen3.5-27B may underperform on:
- Complex generics and associated types
- Protocol-oriented design patterns
- Platform-specific API knowledge (Core Data, CloudKit, etc.)

Mitigation: keep Claude as fallback, use swiftblade for simpler tasks (UI,
boilerplate, tests). Evaluate before full switchover.
