Locara

02 — Manifest (locara.json)

The manifest is the central design artifact. Everything review, runtime, and registry rely on it.

Top-level structure

{
  "schema": "locara/v1",
  "name": "transcribe",
  "publisher": "kingtongchoo",
  "version": "0.1.0",

  "displayName": "Transcribe",
  "description": "Fully-local audio and meeting transcription.",
  "longDescription": "...",
  "license": "Apache-2.0",
  "homepage": "https://example.com/transcribe",
  "repository": "https://github.com/kingtongchoo/transcribe-locara",
  "author": { "name": "King Tong Choo", "email": "..." },

  "icon": "./public/icon.png",
  "screenshots": ["./screenshots/main.png", "./screenshots/search.png"],
  "category": "productivity",
  "tags": ["audio", "transcription", "meetings"],

  "capabilities": { ... },
  "profiles": { ... },
  "storage": { ... },
  "entry": { ... },
  "build": { ... }
}

Field reference

Identity

FieldRequiredTypeNotes
schemayesstringLocked to "locara/v1" for spec v1.
nameyesstringLowercase, alphanumeric + hyphens. Unique within publisher.
publisheryesstringMust match verified publisher account.
versionyesstringStrict semver (MAJOR.MINOR.PATCH).

The full app identifier is <publisher>/<name>@<version> — e.g., kingtongchoo/transcribe@0.1.0.

Display

FieldRequiredTypeNotes
displayNameyesstringShown in catalog. ≤40 chars.
descriptionyesstringOne-line. ≤140 chars.
longDescriptionnostringMarkdown. App-page body.
licenseyesstringSPDX identifier.
homepagenoURLProject site.
repositorynoURLSource repo. Required for verification.
authoryesobject{ name, email, url? }
iconyespath512x512 PNG, ≤200KB.
screenshotsyesarrayAt least 1, max 5. PNG/JPG, ≤2MB each.
categoryyesstringOne of [enumerated categories].
tagsnoarrayFree-form, max 10.

Modalities & Tooling (developer-facing primary declarations)

See 04-modalities.md for full reference. These are the high-level declarations developers use; they expand into capabilities + models + SDK access deterministically.

"modalities": [
  "speech-to-text",
  "text-to-text"
],
"tooling": [
  "filesystem.search",
  "code-exec.python"
]

Apps can declare modalities/tooling in either simple form (just names) or expanded form (with overrides for specific models). Most apps use the simple form; the framework picks defaults.

Capabilities (low-level, mostly auto-derived)

See 03-capabilities.md for full reference.

Most capability declarations are auto-derived from modalities + tooling. Power users can declare them directly when they need precise control.

"capabilities": {
  "net": false,
  "fs": {
    "user-selected": "read-write",
    "app-data": "read-write"
  },
  "device": {
    "microphone": true,
    "camera": false,
    "screen-recording": false
  },
  "models": [
    "whisper-large-v3-q4@sha256:abc...",
    "qwen2.5-3b-instruct-q4@sha256:def..."
  ],
  "tools": ["wasm.text-utils@1.0"],
  "ipc": []
}

All keys are required. Omitting a key implies false / [] / minimal — but explicit is required for clarity and review tooling.

Profiles

Device-tier hardware requirements. Authors define what the app needs at each tier; the registry filters apps by user device fit.

"profiles": {
  "low":  {
    "min_ram_gb": 8,
    "min_disk_gb": 4,
    "models_override": { "transcribe": "whisper-base-q4@sha256:..." }
  },
  "mid":  {
    "min_ram_gb": 16,
    "min_disk_gb": 8
  },
  "high": {
    "min_ram_gb": 32,
    "min_disk_gb": 16,
    "models_override": { "chat": "qwen2.5-7b-instruct-q4@sha256:..." }
  }
}

The models_override swaps in different model variants per profile. Models referenced in overrides must also exist in capabilities.models[] (or be declared specifically with override prefix).

At least one profile must be declared. Most apps will have mid and high; low is encouraged for accessibility.

Storage

"storage": {
  "schema": "./db/schema.sql",
  "migrations": "./db/migrations",
  "vector": { "engine": "sqlite-vec" }
}
FieldRequiredNotes
schemayesPath to schema.sql. CREATE TABLE statements, etc.
migrationsnoDirectory of timestamped migration scripts.
vector.engineno"sqlite-vec" (default), "zvec", or omit if app uses no vectors.

Migrations are auto-generated by locara from schema diffs between versions, but can be hand-edited for non-trivial cases. See 08-storage.md.

Entry

"entry": {
  "frontend": "./src/main.tsx",
  "preload": "./src/preload.ts"
}

Tauri entry points. frontend is the main webview entry; preload is optional (rarely needed).

Build

"build": {
  "tauri_config": "./src-tauri/tauri.conf.json",
  "icon_set": "./src-tauri/icons"
}

Pointers to Tauri build artifacts. Generated by locara init; rarely edited.

Validation

The CLI runs locara verify which checks:

  1. Schema validity. JSON schema (@locara/manifest) validates structure.
  2. Identity consistency. name, publisher, version match local config + git.
  3. File existence. Icon, screenshots, schema, entry files all exist.
  4. Capability reasonableness. Declared capabilities are well-formed; no unknown keys.
  5. Profile consistency. All models_override references exist; profiles ordered low→high by RAM.
  6. Model hashes. All model entries have valid SHA pins (or ? placeholder for dev mode).
  7. Static analysis vs capabilities. AST scan of source — does the app try to use APIs it didn’t declare? (Run automatically; opt out only with explicit --skip-static-analysis.)
  8. License. SPDX validity.

Submission to registry requires locara verify passing without warnings.

Lockfile (locara.lock.json)

Auto-generated, committed to version control. Pins:

  • Resolved model hashes (from registry queries)
  • SDK + components versions
  • Sub-dependency tree
{
  "models": {
    "whisper-large-v3-q4": {
      "sha256": "abc123...",
      "size_bytes": 1234567890,
      "url": "https://cdn.locara.app/models/whisper-large-v3-q4-abc123.gguf"
    }
  },
  "sdk_version": "0.1.4",
  "components_version": "0.1.2"
}

The lockfile makes builds deterministic. CI uses it; hand-editing is discouraged but allowed.

Versioning

  • Patch (0.1.0 → 0.1.1): bug fixes, no capability changes. Auto-published.
  • Minor (0.1.0 → 0.2.0): new features, no capability expansion. Reviewed if anything new.
  • Major (0.1.0 → 1.0.0): breaking changes. Always reviewed.

Capability changes are independent of version semantics. Any capability expansion (gaining net: true, or adding a new model with sensitive capability) triggers a 7-day cool-down + user re-consent on update — regardless of version bump. See 14-trust-safety.md.

Schema versioning

The schema field lets us evolve the manifest format:

  • v1 apps continue to work. Forever.
  • Future versions (locara/v2, etc.) introduce new fields and patterns.
  • The runtime supports all schema versions (long-term support, SQLite-style commitment).

A v1 manifest written today must still parse and run in 5 years. This is a hard commitment; design accordingly.

Open questions

  • (open) Should category be enumerated (closed list) or free-form? Probably enumerated to keep catalog filtering tractable.
  • (open) How granular should tags be moderated? Spam prevention for SEO-style tag stuffing.
  • (open) Should the manifest reference minimum SDK version? Probably yes — "requires_sdk": ">=0.2.0".
  • (open) Multi-locale display fields (i18n)? Not v1; punt.

Cross-references