API Documentation

SwiftGuard scans Swift source code for concurrency issues using tree-sitter AST parsing. It previews what Swift 6 strict concurrency would flag, plus catches @unchecked Sendable misuse that the compiler explicitly skips.

POST/api/v1/review

Analyze a single Swift source string. Returns concurrency issues with line numbers, confidence scores, and fix suggestions.

Authentication

Pass your API key via the Authorization header. Demo key: sg_demo_key_2026 (rate-limited to 100 req/min).

Request Body

{
  "source": "actor Counter { var count = 0 }\nfunc inc(c: Counter) { c.count += 1 }",
  "swiftVersion": "6.0",     // optional
  "platform": "ios"          // optional
}

source (required) — Swift source code as a string.

swiftVersion (optional) — Target Swift version. Default: latest.

platform (optional) — Target platform (ios, macos, server). For future use.

Response

{
  "issues": [
    {
      "rule": "actor-isolation-violation",
      "severity": "error",
      "message": "Direct access to actor-isolated property 'count' from non-isolated context.",
      "line": 2,
      "column": 34,
      "confidence": 0.90,
      "suggestion": "Use 'await' to access actor-isolated state asynchronously.",
      "seProposal": "SE-0306"
    }
  ],
  "metadata": {
    "rulesApplied": 6,
    "parseTimeMs": 3,
    "astValid": true
  }
}
POST/api/v1/scan-repo

Scan an entire GitHub repository for concurrency issues. No authentication required.

Request Body

{
  "repoUrl": "https://github.com/owner/repo",
  "branch": "main"     // optional, defaults to default branch
}

Response

{
  "repo": "owner/repo",
  "branch": "main",
  "filesScanned": 42,
  "filesWithIssues": 8,
  "scanTimeMs": 1250,
  "summary": { "errors": 3, "warnings": 12, "info": 5 },
  "topFiles": [
    { "path": "Sources/NetworkManager.swift", "issues": 4 }
  ],
  "issues": [ ... ]
}

Limits: 500 files max per scan. Test files are skipped. 30-second timeout.

GET/badge/[owner]/[repo]

Returns a live SVG badge showing your repo's concurrency health. Green (clean), amber (warnings), red (errors). Cached for 1 hour.

Usage

Add this to your README:

![SwiftGuard](https://swiftguard.kiloloco.com/badge/owner/repo)

Or in HTML:

<a href="https://swiftguard.kiloloco.com">
  <img src="https://swiftguard.kiloloco.com/badge/owner/repo" alt="SwiftGuard Badge" />
</a>

Rules Reference

SwiftGuard runs 6 concurrency-focused rules against each file.

Rule IDSeverityConfidenceSE ProposalDescription
unsafe-unchecked-sendablewarning0.85–0.90SE-0302@unchecked Sendable with mutable state and no visible synchronization. The compiler skips these by design.
actor-isolation-violationerror0.85–0.95SE-0306Actor state accessed from Task.detached, nonisolated methods, or cross-actor without async.
non-sendable-boundary-crossingwarning0.80–0.95SE-0302Non-Sendable types captured in Task closures or crossing concurrency boundaries.
task-data-race-riskerror0.88–0.92SE-0304Mutable variables captured and mutated inside Task closures.
missing-sendable-closurewarning0.85SE-0302Closure types in actors or @unchecked Sendable classes missing @Sendable annotation.
missing-sendable-conformanceinfo0.75SE-0302Types used as actor method parameters without Sendable conformance.

Code Examples

Single file review (curl)

curl -X POST https://swiftguard.kiloloco.com/api/v1/review \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer sg_demo_key_2026" \
  -d '{"source": "actor Counter { var count = 0 }\nfunc inc(c: Counter) { c.count += 1 }"}'

Repo scan (curl)

curl -X POST https://swiftguard.kiloloco.com/api/v1/scan-repo \
  -H "Content-Type: application/json" \
  -d '{"repoUrl": "https://github.com/owner/repo"}'

Badge (Markdown)

![SwiftGuard](https://swiftguard.kiloloco.com/badge/owner/repo)

How It Works

  1. Files are parsed into ASTs using tree-sitter-swift.
  2. A first pass builds a TypeRegistry for cross-file Sendable resolution.
  3. A second pass runs 6 concurrency rules against each AST.
  4. Issues include code snippets and SE proposal references.

What it catches that the compiler does not

@unchecked Sendable is an explicit opt-out from the compiler. When a type is marked @unchecked Sendable, the compiler performs zero concurrency checks on it. SwiftGuard audits these escape hatches — flagging mutable state without visible synchronization, even when the compiler looks the other way.

Limitations

  • Most rules preview what Swift 6 strict concurrency mode would catch. Enable strict concurrency in your project for authoritative results.
  • Cross-file type resolution works within the scanned repo but cannot resolve types from external SPM packages.
  • 500 file limit for web scans.