TaskProvider boundary (ADR-001)
Mainark routes task-graph I/O through TaskProvider so backends can be swapped without rewriting CLI/pipeline callers.
Status
| Item | Status |
|---|---|
| Active default backend | SQLite (TASK_BACKEND=sqlite) — ADR-001 Phase 4 |
| Linear rollback | Opt-in (TASK_BACKEND=linear + LINEAR_API_KEY) |
| Beads | Stub only — design review: SQLite prior stands (spike) |
| Local task store | issues + work_status / plan_md / issue_events / id_sequences |
Entry points
| Caller | Factory | Notes |
|---|---|---|
| Orchestrator / pipeline | getTaskProvider() | Uses config().taskBackend |
| CLI | createCliTaskProviderFromEnv(dotenv) | Backend-aware; sqlite needs no Linear key |
# Default local task store (ADR-001 Phase 4)
TASK_BACKEND=sqlite
# Relative paths resolve against MAINARK_HOME (not target-repo cwd). Absolute is safest.
SQLITE_PATH=./data/orchestrator.db
# LINEAR_API_KEY not required for issue CRUD / implement queue when sqlite
Migrating off Linear
mainark import-linear --dry-run # preview
mainark import-linear # copy FUL-* into SQLite (ids, blockers, plans)
# TASK_BACKEND=sqlite is already the default
# Free plan is capped at 250 issues — clear closed Linear copies after import:
mainark purge-linear --dry-run
mainark purge-linear --confirm # Done + Cancelled only (default)
# mainark purge-linear --confirm --all-imported # dangerous: every imported copy
# then: Linear → Settings → Administration → Billing → cancel/downgrade
Import preserves display ids (FUL-n), blocker edges, parent links, labels, and ## Mainark plan bodies.
import { getTaskProvider, createCliTaskProviderFromEnv } from "@/tasks";
await getTaskProvider().onPickedUp(uuid);
const tasks = createCliTaskProviderFromEnv(dotenv);
await tasks.createIssue({ title: "…" });
Intentionally outside / deferred
| Item | Why |
|---|---|
| Linear client internals | Still used by LinearTaskProvider (rollback until Phase 5) |
| Fulreach CI → Linear comments | Phase 5 |
| Beads SoT | Rejected in design review |
Phase 3 checklist (automated vs human)
Automated in tests/unit/sqliteTaskProvider.test.ts: create/edit, deps, epic plan, queue, claim, events, offline factory, pause/resume reconcile.
Human soak before Phase 4 (signed for default flip): implement, publish, review, worktree lifecycle on sqlite SoT.