Native Task System¶
Canonical SQLite task authority with revision-checked mutations, projection-free Co-work knowledge documents, durable cutover safety, and frozen legacy imports.
Details¶
Native task authority¶
TaskStore and TaskApplicationService are the sole source of truth for live task identity, fields, state, completion, archive/trash lifecycle, structured tags, action items, history, provenance, and document links. Obsidian, tasks/master-task-list.md, tasks/archive.md, task-note Markdown, and the Obsidian Tasks plugin are not runtime readers, writers, mirrors, or reconciliation peers after activation.
Every mutation returns the task ID, task revision, collection revision, and a durable mutation receipt. Callers should pass the current expected_revision and may pass a stable client_mutation_id; retries with the same semantic request replay, while stale revisions produce a structured conflict instead of overwriting newer work. Completion accepts an optional historical done_date; snoozing uses the explicit snooze_until field.
Projects and namespaces¶
A task may link to zero, one, or several registered projects through
project_ids, a list of stable positive integer registry IDs. Project names,
slugs, aliases, and folders belong to the Projects registry; namespaces are
independent task organization. Renaming or flattening a namespace does not
change project links, and linking a project does not create a namespace.
Ordinary tags and namespace assignments also remain distinct.
The explicit legacy project create argument accepts a registry slug or alias
as a compatibility ingress. It is never inferred from a newly supplied tag.
Callers must consume project_ids rather than select an arbitrary primary
project from a task with several links. Existing links survive registry renames,
soft deletion, or temporary registry unavailability; adding an unknown ID fails
validation.
Historical associations that cannot be resolved uniquely are returned in
unresolved_projects with legacy_value, source_tag, reason, and
candidate_ids. No project is silently created or association discarded.
In task detail, choose the intended registered projects and explicitly remove
the historical references being replaced. The revisioned update combines
project_ids with remove_unresolved_projects, whose entries are historical
values, and preserves every unchecked reference. Omitting either field leaves
that part unchanged. A task with unresolved associations is not a task with no
project.
Namespace changes use a reviewed preview, atomic apply, and conditional durable
undo. See tasks/namespace-organization for scope and API contracts.
Batch creation validates every accepted row before opening its transaction, then rechecks all task IDs against existing task rows and non-aborted aggregate creation reservations under the same write lock. Any collision aborts the whole batch before an accepted task is published.
Atomic creation and attachment¶
A scalar-only task is created in one TaskApplicationService transaction. When
creation includes a Co-work knowledge document,
TaskAggregateCreationService and TaskCreationCoordinator own a recoverable
cross-store state machine:
- validate the complete task request before reserving cross-store state;
- atomically reserve the explicit or deterministic task ID in
task_creation_intents; - prepare the projection-free document, provenance state, requested Truth policy, and pending local admission;
- freeze every participant receipt into the coordinator decision and admit the document against that decision;
- publish the task row, document link, and field-derivation receipts together.
Ordinary task readers cannot see a partial aggregate because the task row does not exist until publication. Replaying the same client mutation resumes the same participants, and reconciliation rolls recoverable intents forward without duplicating a task, document, binding, admission, or receipt.
Attaching a first document to an existing task uses a separate durable intent. It validates task existence, liveness, revision, and the one-document limit before the first scoped-store reservation, then links and admits the prepared document under the recorded expected task revision. Recovery resumes the same deterministic document and binding identities.
Co-work knowledge documents¶
Task notes are ordinary Co-work knowledge documents with projection_mode=none. They are not Markdown files and are never rendered back into the vault. Browser edits, task reads, email append, IR parsing, excerpts, and restore all consume the current structured/Yjs head. A task can also hold opaque links to local files in place: the browser receives display metadata and a host action, never an absolute path or copied/encrypted asset unless a separate feature explicitly requests that.
Migration and frozen legacy data¶
Migration is backup-first and operator-driven. The inventory includes ID-bearing and ID-less task lines, task metadata, note bodies, attachments, missing references, and unattached notes; the importer assigns deterministic native IDs, creates projection-free Co-work documents, and emits a recovery catalog. Dry-run and parity checks happen before the guarded prepare/fence/activate sequence.
The live cutover is never implicit in application startup, tests, import, or dashboard use. The backed-up legacy task files and database snapshot remain frozen and retained indefinitely until the user explicitly decides otherwise. No 30-day cleanup or automatic deletion is permitted.
Rollback exports retain independent project links, unresolved associations, and
their migration provenance in native-supplement.json. The export warns that
the historical UI cannot edit these independent references. Namespace paths are
preserved as stored; export does not manufacture project tags as a substitute.
Secondary consumers¶
Task context, project task counts, Obsidian context summaries, Chrome/email/Journal routing, completeness, search/IR, MCP skills, and both dashboard entry points query the native domain after activation. Project counts use independent associations and count a task once per linked project. The disabled sidecar_jobs/task-sync.md file remains only as historical configuration.