DreamLake

Tasks and linked Notes

The deployment record documents staging and production Tasks delivery on 2026-09-14, including hosted acceptance and the docs/skill release. See #301 and its receipt for the tested versions. Verify current CLI help and the target server before running operations; that historical receipt is not a fresh availability check.

Storage and scope

Task is an optional tracking structure, independent of execution scheduling. Existing Notes are unchanged. Namespace and existing project Node ownership and content read/create/delete permissions apply to every route.

Task fields: stable ObjectId, namespaceId, projectNodeId, materialized path, slug, title, blurb, kind, text tags, status, ordered children IDs, role-based Note references, optional progress, actual startedAt/endedAt, nullable reviewedAt/acceptedAt, deletedAt, revision, createdBy/createdAt/updatedAt. API revisions are decimal strings.

Kinds are free text, normally agenda/workstream/stage/task. No Stage, Workstream or Attempt model. Sessions remain a chat integration; Pipeline, Workflow and TrackedRun retain execution ownership.

One structural parent per task; roots have no parent. Child order is the parent's children array. Paths are project-unique, at most 32 levels. Create ancestors first. Moves preserve IDs and atomically update descendant paths, reject cycles/collisions, and are bounded to 1,000 descendants. Cross-references belong in Notes. Soft-deleted paths remain reserved for restoration.

Note links have role, existing noteId and optional section key. Roles include agent_prompt, comment, details and acceptance. Linking needs access to the existing Note in the same namespace; reads omit inaccessible references. Section keys are references, not validated editor anchors. A text-only task needs no Note. Do not duplicate Note bodies in Task metadata.

State and events

Status is not_done, done or deprecated. Soft deletion is separate, refuses live children and preserves children placement/history/Notes. Restore requires a live parent.

Progress is an absolute {mode, completed, total?, unit} snapshot. Discrete values are nonnegative safe integers; continuous values are finite nonnegative numbers; total must be >= completed. Missing total means unknown, including replacement of a known total. Mode/unit remain fixed until reopen. No mixed-unit or recursive numeric rollup is implied.

Start/end are explicit actual times. End may be known with unknown start; a known end cannot precede a known start. End does not mark done. Progress and done never imply human acceptance. Reviewed/accepted projections remain null in this delivery: a human review identity/evidence protocol is still a design extension.

TaskEvent records eventId, taskId, actor, type/data, occurredAt, receivedAt and taskRevision. Supported client events: started, ended, progress, status_changed, reopened, message, evidence. Structural changes generate server audit events. Same task/eventId, actor and normalized payload replay; a changed payload conflicts. State changes require the task's expectedRevision. The event and new projection commit transactionally. Reopen clears current-cycle progress/start/end/review/acceptance, while preserving history.

Event order and cursors use server taskRevision, not client clocks or Mongo IDs. Context/evidence can preserve historical occurrence times. No separate historical state replay mode. Evidence is an HTTP(S) reference; PR dates never populate task timing.

HTTP

Base: /namespaces/:namespace/projects/:project/tasks.

  • GET/POST base: list/create. List supports prefix, cursor, limit (max 200), includeDeleted.
  • GET /resolve?path=...; GET/PATCH/DELETE /:id.
  • POST /:id/move with path; PATCH /:id with children reorders the full existing set.
  • POST /:id/restore.
  • GET /:id/status: task, immediate child summaries, explicitly labeled immediate-child status rollup. Deprecated children excluded from the done denominator.
  • GET/POST /:id/events: cursor is taskRevision; max 200; includeDeleted for history.
  • GET/POST/DELETE /:id/notes.

Mutations carry expectedRevision in JSON except creation and contextual events. Re-read on 409; never silently overwrite or retry a changed intent. Event retries must preserve the exact event body including expectedRevision and occurredAt.

Enable TASKS_ENABLED=true only after tasks:ensure-indexes succeeds. Startup verifies the actual unique and query indexes. This requires MongoDB transactions/replica set. Index changes are additive; Notes schema is unchanged.

Display and text links

UI: /:namespace/tasks?project=:slug and /:namespace/tasks/:id?project=:slug. Folder outline, waterfall, explicit start/end/status/progress controls, reorder/move, soft delete/restore, linked Notes and event history. Display title + blurb. Open recorded work uses a striped bar to now; unknown start/end are not fabricated. Refresh reads the current projection.

markdown
1. **Write recovery** — Safely retry a write. <!-- task: [write-recovery](https://dreamlake.ai/ge/tasks/TASK_ID?project=my-project) -->

   Parent-context detail belongs to this source Note.

Hidden links retain stable target IDs; indented multiline text belongs to the source list item, not automatically to the target Note. Keyed nested items can identify child associations. AI-assisted text/structure reconciliation remains proposed; this delivery does not scan or rewrite Notes. Arbitrary unkeyed lists remain text.

Install the Tasks skill

Download the Tasks skill and unpack the dreamlake-tasks directory into your agent’s skills folder. The archive includes the contract and operation examples. Native CLI 0.19.0 provides task commands; the skill is distributed separately as this archive.