Workspace task management architecture
Canonical Octonode repository documentation.
Workspace task management architecture
Date: 2026-08-03
Status: Core milestone implemented; advanced administration remains optional
Engineering plan: Task management implementation plan
Decision
Octonode adds Tasks as a top-level workspace capability. A Task Space is a planning
container inside the active personal, organization, or team workspace. It is deliberately not an
Octonode project: projects own code, workflows, runs, and repository links, while Task Spaces own
planning views, types, fields, statuses, sprints, releases, and work items. A work item may link to
several projects, workflows, or pull requests without changing any source or .octonode authority.
The developer-only apps/tasks, TASKS.json, and BUGS.json are unrelated. Product Tasks must not
read them, import them, migrate them, replace their UI, alter their build, or delete them. They remain
an independent repository-maintainer tool outside this architecture.
Implemented milestone
The current milestone ships the cloud-backed task_management capability, the top-level Studio
Tasks workspace, generated OpenAPI client, and workspace-scoped Durable Object persistence. Users
can create simple, Kanban, or Scrum spaces and Initiative, Epic, Story, Task, Bug, or Subtask items;
search, update, and move work; use Board, List, Calendar, Timeline, sprint/backlog, and release
projections; create tags, sprints, and releases; comment and inspect activity; attach workflow or
pull-request links; and share a task permalink in Chat. Social schema v8 includes task data in
logical backup, restore, and workspace deletion.
The rest of this document is the target architecture. Type/field/view administration, My Work and Initiatives roll-ups, contextual Calendar/Timeline editing, workflow execution from a task, live pull-request resolution, rich Chat cards, and expanded operational/visual acceptance evidence remain optional follow-up work. The generated OpenAPI document is the authority for the routes implemented by the current milestone.
The product combines a simple default surface with Jira-like depth through progressive disclosure:
- every Task Space starts with Board, List, and Calendar views and three statuses;
- Scrum spaces additionally expose Backlog, Active Sprint, and sprint planning;
- hierarchy, releases, estimates, dependencies, Timeline, saved views, typed columns, and integrations remain available but do not crowd the default create/edit flow;
- every view offers inline creation with a full work-type picker and inherits the clicked row/group's status, sprint, release, date, parent, or tag context;
- all work item types use one shared status model rather than a workflow designer per type.
The fixed hierarchy levels and built-in types are:
Initiative
└─ Epic
└─ Story | Task | Bug
└─ SubtaskEvery item belongs to exactly one Task Space. An Initiative may parent Epics from other Task Spaces in the same workspace; every other parent/child pair must remain in one Task Space. This supplies a workspace portfolio without making Task Spaces another authorization boundary.
Research basis and limits
Jira's public APIs expose product resources, not Atlassian's private implementation architecture. This design therefore copies useful semantics, not undisclosed internals:
- Jira separates platform work-item operations (items, comments, links, transitions) from Jira Software planning resources (boards, backlogs, epics, and sprints). Octonode keeps one Tasks API module but preserves the same conceptual split between durable work and query-based views.
- Jira defines the default hierarchy as Epic, standard items such as Story/Task/Bug, and Subtask; premium plans may add Initiative-like levels. Octonode fixes the useful four-level hierarchy and does not build a hierarchy editor.
- Jira's backlog is derived from incomplete items outside future or active sprints, and its sprint resource has future, active, and completed lifecycle states. Octonode uses the same derivation and lifecycle with one active sprint per Task Space.
- Jira Calendar and Timeline are projections over item dates, hierarchy, and dependencies. They are not separate copies of the work.
- Jira permits work-item creation directly in List, Board, Backlog, and Timeline contexts, with the selected type and grouping values inherited by the new item. Octonode uses the same contextual quick-create rule in every view.
- Jira versions are exposed to software teams as Releases, including progress and an explicit choice for unresolved work when a version is released. Octonode models a Release as Task Space planning data rather than a Git tag or deployment.
- Jira supports custom work types and many field types. Octonode allows custom names at four fixed hierarchy levels and a bounded set of typed columns, without schemes, formulas, or plugins.
- GitHub Projects supports table, board, and roadmap views over the same items and typed fields. Octonode similarly persists saved view definitions, never card membership or a second board copy.
Primary references:
- Jira Software board API
- Jira Software sprint API
- Jira Cloud work item API
- Jira work type hierarchy
- Jira custom work types
- Jira inline List creation
- Jira project version API
- Jira Releases
- Jira field types
- Jira Calendar
- Jira Timeline
- GitHub Project views
- GitHub Project fields
- GitHub pull request links
Jira Cloud is not a runtime dependency or initial synchronization authority. A one-time importer can be added later against the public APIs, but continuous Jira synchronization would create two writers and is outside this architecture.
Product model
Workspace
The existing workspace remains the tenant, authorization boundary, backup unit, realtime audience,
and billing scope. Task data never crosses user:<id>, org:<id>, or team:<id> boundaries.
Task Spaces do not have separate memberships. If private team boards are later required, use a Team
workspace rather than adding per-space ACLs.
Task Space
A Task Space has a UUID, immutable uppercase key, name, optional description, sprint-enabled flag, and archive state. Creation offers three templates that only seed types, statuses, and views:
| Template | Seeded behavior |
|---|---|
| Simple | To do, Doing, Done; Board, List, Calendar; sprints hidden |
| Kanban | Backlog, Ready, In progress, Review, Done; Board/List/Calendar; sprints hidden |
| Scrum | Backlog, Ready, In progress, Review, Done; Backlog/Active Sprint plus Board/List/Calendar |
There are not three engines. After creation, templates disappear into the same statuses, views, and
sprintsEnabled flag. A space key becomes permanently immutable as soon as the space is created so
human links such as OPS-142 stay valid.
Archiving hides a Task Space but preserves all item links and history. User-facing hard deletion is not provided; complete workspace deletion remains the destructive erasure path.
Work item types
Every Task Space starts with Initiative, Epic, Story, Task, Bug, and Subtask. Space managers may add, rename, reorder, recolor, or archive types at one of four fixed levels:
initiative | epic | standard | subtaskExamples of custom standard types are Feature, Chore, Incident, or Research. A type's level cannot change after creation, and a type in use cannot be deleted; archiving removes it from future create menus while preserving existing items. There are no global type schemes. The four levels supply all parent validation, roll-ups, sprint rules, and view behavior.
Every create entry point—global Create, Board column, List row/group, Backlog position, sprint, Calendar date, Timeline parent row, and Release detail—shows all active types valid for that context. Quick create asks only for type and title, inherits the surrounding context, and opens the full form only when a required parent or field is missing.
Work item
Every item has a stable UUID and a human key formed from its immutable Task Space key and monotonic number. The first release supports only fields with demonstrated use:
type WorkItem = {
id: string;
key: string;
spaceId: string;
type: {
id: string;
name: string;
level: "initiative" | "epic" | "standard" | "subtask";
builtin: "initiative" | "epic" | "story" | "task" | "bug" | "subtask" | null;
};
title: string;
description: string | null; // Markdown, raw HTML disabled when rendered
statusId: string;
priority: "highest" | "high" | "medium" | "low" | "lowest";
reporterId: string;
assigneeId: string | null;
parentId: string | null;
sprintId: string | null; // standard-level items only; subtasks inherit
storyPoints: number | null; // standard items only
startAt: number | null;
dueAt: number | null;
rank: number;
version: number;
createdAt: number;
updatedAt: number;
archivedAt: number | null;
};Tags and releases are normalized many-to-many values rather than JSON inside the item. Description and comments use the existing safe Markdown renderer. Type conversion is allowed only between types at the same hierarchy level. Cross-level conversion, moving an item to another Task Space, and hard deletion are excluded initially because each requires key aliases and parent/sprint/release repair.
Tags and typed fields
Tags belong to a Task Space and have a stable ID, unique normalized name, color, and archive state. Items may carry several tags. Tags appear as first-class List columns and Board card chips and are available in quick create, grouping, filters, search, Calendar, Timeline, Releases, and reporting.
Space managers may add up to a bounded number of lightweight custom fields. Supported value types are
text, number, single_select, multi_select, date, checkbox, user, and url. A field has a
name, type, description, required flag, options where relevant, display order, and archive state. Its
type cannot change after values exist. Values are schema-validated against the definition and stored
in work_item_field_values; no arbitrary object value crosses the API.
List views can add, remove, and reorder built-in or custom columns without changing the Task Space schema. Inline cell editing uses native controls. Board grouping additionally accepts a single-select custom field; Calendar/Timeline may use a configured custom date column as their date source. Formula, rollup, rich-object, cross-workspace relation, and plugin field types are not supported.
Statuses and board movement
Statuses belong to one Task Space and have a display name, stable ID, category
todo | in_progress | done, order, optional WIP limit, and archive state. Every item type shares the
same status set. There is no transition graph or per-type screen scheme.
A Board is a saved query grouped by status. Moving a card updates status and rank in one Durable
Object transaction using If-Match item version. Ranks use spaced integers; the affected column is
renumbered only when no midpoint remains.
ponytail: column renumbering is intentionally bounded and simple. Replace it with fractional ranks
only if measured large-column moves make the mutation SLO fail.
Sprints and backlog
A sprint belongs to one sprint-enabled Task Space and has future | active | completed state, name,
goal, start/end dates, and version. Only one sprint may be active in a Task Space. Only standard-level
records are assigned directly; a Subtask inherits its parent's sprint. Initiative- and Epic-level
types span sprints.
Backlog is derived, not persisted:
not archived
AND status.category != done
AND type.level = standard
AND sprint_id IS NULLStarting a sprint validates dates and the one-active-sprint invariant. Completing it atomically marks it completed and moves incomplete items to either a selected future sprint or the backlog.
Releases
A Release belongs to one Task Space and has a stable ID, name, optional description, status
unreleased | released | archived, optional start date, required target/release date when released,
and version. Work items may belong to multiple releases through work_item_releases, matching the
common need for one change to be backported or delivered in several versions.
Release progress is derived from linked items by status category and story points; it is never stored as another counter. Release detail shows linked items, status/assignee/type/tag breakdowns, and the current linked pull request state already available on each item. Calendar shows release dates and Timeline shows release markers.
Releasing is an explicit version-checked operation. It records the release date and requires a choice for unresolved items: keep them on the released version, move them to one selected unreleased version, or remove the released version assignment. It does not create Git tags, GitHub Releases, deployments, or package versions; those remain separate source/deployment authorities and may be linked later.
Links and activity
Parenthood is distinct from work-item links. The initial directional link types are blocks,
duplicates, and relates; the UI supplies the inverse wording. Duplicate/self links are rejected.
Each mutation writes one compact append-only activity event in the same transaction as the item. Events record actor, event kind, changed field names, bounded before/after scalars, and timestamp. Full description bodies are not copied into history. Comments are versioned records with edit and delete tombstones, author/moderator rules, Markdown, and workspace notifications.
The first release has no arbitrary file uploads. Links to workflows and pull requests cover the requested engineering attachments without adding malware scanning, retention, and R2 quota policy.
Saved views
A view stores a name, layout, typed filter, grouping, sort, and revision:
type TaskView = {
layout: "board" | "list" | "calendar" | "timeline";
filter: {
query?: string;
typeIds?: string[];
statusIds?: string[];
priorities?: WorkItem["priority"][];
assigneeIds?: string[];
tagIds?: string[];
sprintId?: string | null;
releaseIds?: string[];
parentId?: string;
projectIds?: string[];
customFields?: Array<{
fieldId: string;
operator: "is" | "is_not" | "contains" | "before" | "after";
value: unknown;
}>;
startFrom?: number;
dueThrough?: number;
hideDone?: boolean;
};
groupBy:
| "status"
| "assignee"
| "priority"
| "type"
| "tag"
| "sprint"
| "release"
| "custom_single_select"
| "none";
sort: "rank" | "updated" | "due" | "priority";
columns: Array<{ field: string; width?: number }>;
};Filters are AND-only and schema-validated. This covers the common Monday/Jira views without a JQL parser, arbitrary formulas, or user-authored SQL. Board membership, Calendar entries, Timeline bars, and My Work are projections over the same work items.
Integration behavior
Workflows and executions
work_item_workflow_links stores only (workItemId, projectId, workflowId) plus creator and time.
Before writing, the service resolves the project and workflow inside the same workspace using the
existing authorities. Reads batch-resolve current names and availability; a deleted or inaccessible
workflow renders as unavailable without destroying the historical link.
Phase 1 offers Open workflow. A later phase may offer Run through the existing schema-driven workflow input dialog and record the successful execution ID. Task fields are never injected into a workflow implicitly, and the browser never receives an execution credential it did not already have.
GitHub pull requests
work_item_pull_links stores (workItemId, repositoryId, pullNumber) and audit fields. The Cloud API
validates that the existing architecture_repository_links record belongs to the active workspace before
writing. Pull request title, URL, author, state, and head SHA remain GitHub-owned data mirrored in D1;
they are composed into task responses and are not copied into the workspace object.
The first release links and unlinks an existing pull request explicitly. It reuses the current GitHub App, cached pull request records, webhook verification/deduplication, and realtime invalidation. Octonode tasks are not mirrored to GitHub Issues, so the App does not request broader Issues permissions. A later convenience may recognize an exact Octonode task permalink in a pull request body, but branch/title heuristics do not silently create links.
Chat sharing
Every work item has a canonical Studio permalink. Sharing a task in Chat sends that permalink as
ordinary message Markdown; no second mention table or chat/task transaction is required. The chat
controller recognizes same-origin task links and batch-resolves the visible page's keys through the
Tasks API for compact cards. It rechecks tasks:read; an inaccessible, archived, or removed target
renders a neutral unavailable link rather than leaking title, assignee, or status.
Notifications
Assignment, mention, comment reply, and sprint lifecycle notifications reuse the existing workspace notification table and WebSocket. Notifications carry item ID/key plus bounded display metadata, not full descriptions or comment bodies.
Persistence authority
Hosted Tasks extends the existing workspace collaboration Durable Object instead of creating a second task database. The object is already deterministically keyed by workspace, owns strongly consistent collaboration writes, hibernating WebSockets, generations, write fencing, backup, and deletion. Cloudflare recommends one Durable Object per logical coordination unit such as a tenant workspace and SQLite for relational state; this workspace is the correct atom. See Cloudflare's Durable Object design rules and SQLite storage API.
| Data | Authority | Projection/cache |
|---|---|---|
| Workspace membership and task permissions | Existing control D1 | Request authorization context |
| Task Spaces, types, fields, statuses, sprints, releases, tags, views | WorkspaceSocialObject SQLite | React Query |
| Work items, tags, hierarchy, links, comments, activity | WorkspaceSocialObject SQLite | React Query + WebSocket invalidation |
| Project/workflow definitions and executions | Existing project/repository/store authority | Batch-resolved task link cards |
| GitHub installation, repository, and pull request state | GitHub mirrored in control D1 | Composed pull request card |
| Chat message containing a task permalink | Existing social chat tables | Rich card resolved at read/render time |
Social schema v8 adds these tables; names are contract-level and may be split across nearby migration files:
task_spaces task_space_statuses
work_item_types task_space_fields
task_field_options task_space_views
task_tags task_releases
task_sprints work_items
work_item_field_values work_item_tags
work_item_releases work_item_links
work_item_comments work_item_watchers
work_item_events work_item_workflow_links
work_item_pull_linksImportant constraints and indexes:
- unique Task Space key and unique
(space_id, item_number); - partial unique index for one active sprint per Task Space;
- parent and linked item foreign keys with restricted deletion;
- unique normalized type/tag/release names per Task Space and unique relation/link tuples;
- field values reference a same-space field definition and match its immutable value type;
- list indexes beginning with
space_idfor status/rank, sprint/rank, assignee/updated, parent/rank, release/date, tags, and archived state; - keyset cursors over stable
(sort_value, id)pairs; never offset-scan an unbounded workspace; - every mutable aggregate has a positive version and every client mutation has an idempotency key.
Task tables join freely with collaboration tables because they share one workspace object. Cross- authority project, workflow, and GitHub checks happen before the synchronous task transaction; the transaction stores identifiers only. No external I/O occurs inside a related SQLite write sequence.
The existing logical export, generation restore, PITR, and workspace deletion lists must include all task tables. No R2 binding is added because arbitrary attachments are excluded.
ponytail: one collaboration/task Durable Object per workspace remains the initial ceiling. Split
tasks by Task Space only if measured request saturation or storage growth approaches platform limits;
the public API and stable UUIDs allow that later without changing the product model.
Configured local-cloud and hosted modes use this authority. A server with no cloud collaboration configuration returns a truthful unavailable capability instead of writing task state into a second filesystem store.
Authorization and trust boundaries
Three workspace actions in the shared schema catalog govern Tasks:
| Action | Allows | Default |
|---|---|---|
tasks:read | Read spaces, items, views, comments, links, and activity | owner/admin/member/team lead/team member/viewer |
tasks:write | Create/edit/archive items; comment; link; move cards; plan sprints | owner/admin/member/team lead/team member |
tasks:manage | Configure/archive spaces, types, fields, tags, statuses, releases, shared views, and sprint settings | owner/admin/team lead |
Every Tasks request resolves the active workspace principal first. Cross-workspace IDs, project IDs,
workflow IDs, repository IDs, item IDs, and comment IDs return 404, not authorization detail.
Agents may receive these actions explicitly and remain intersected with workspace role and optional
project binding. A project-bound agent can link only its bound project/workflows and cannot manage a
workspace Task Space.
Mutations use Zod boundary validation, bounded UTF-8 sizes, idempotency keys, optimistic versions, and synchronous relational checks. Markdown raw HTML remains disabled. Search text is normalized and bounded. Resource limits begin conservative: 100 active Task Spaces per workspace; 20 statuses, 50 work types, 50 typed fields, 500 tags, and 50 saved views per space; 20 tags, 20 releases, and 100 links per item; 240 title characters; and 32 KiB each for description or comment. List endpoints return at most 100 records.
Target API shape
Routes are Hono + Zod documented, generated into the Studio client, and gated by workspace capability. The target surface is:
GET/POST /api/task-spaces
GET/PATCH /api/task-spaces/:spaceId
POST /api/task-spaces/:spaceId/archive
GET/POST /api/task-spaces/:spaceId/statuses
PATCH /api/task-statuses/:statusId
GET/POST /api/task-spaces/:spaceId/types
PATCH /api/work-item-types/:typeId
GET/POST /api/task-spaces/:spaceId/fields
PATCH /api/task-fields/:fieldId
GET/POST /api/task-spaces/:spaceId/tags
PATCH /api/task-tags/:tagId
GET/POST /api/task-spaces/:spaceId/views
PATCH/DELETE /api/task-views/:viewId
GET /api/work-items
GET /api/work-items/previews
POST /api/task-spaces/:spaceId/work-items
GET/PATCH /api/work-items/:itemKey
POST /api/work-items/:itemKey/archive
POST /api/work-items/:itemKey/move
GET /api/work-items/:itemKey/activity
GET/POST /api/work-items/:itemKey/comments
PATCH/DELETE /api/work-item-comments/:commentId
PUT/DELETE /api/work-items/:itemKey/links/:targetKey
PUT/DELETE /api/work-items/:itemKey/workflows/:projectId/:workflowId
PUT/DELETE /api/work-items/:itemKey/pull-requests/:repositoryId/:pullNumber
GET/POST /api/task-spaces/:spaceId/sprints
POST /api/task-sprints/:sprintId/start
POST /api/task-sprints/:sprintId/complete
GET/POST /api/task-spaces/:spaceId/releases
GET/PATCH /api/task-releases/:releaseId
POST /api/task-releases/:releaseId/releaseGET /api/work-items accepts the typed view filter and a keyset cursor. POST .../move is a domain
operation because status and rank must change atomically. Start/complete sprint and release
are operations because they enforce lifecycle and bulk movement. Ordinary scalar changes use PATCH
with expectedVersion.
The server registers the complete route surface for OpenAPI and configured forwarding. Hosted Gateway routing sends control-plane task routes directly to the Cloud API so opening a board does not wake the Sandbox. Workflow resolution/run and repository source operations remain Sandbox-bound; GitHub pull metadata stays control-plane-bound.
Target Studio information architecture
Tasks belongs in the top-level Left Rail, not under one Octonode project.
Tasks
├─ My Work assigned to me across the active workspace
├─ Initiatives workspace roll-up
└─ Task Spaces
└─ OPS
├─ Board
├─ List
├─ Calendar
├─ Timeline progressive disclosure
├─ Backlog sprint-enabled spaces only
├─ Active Sprint sprint-enabled spaces only
├─ Releases
└─ Settings tasks:manage onlyThe main route is /studio/tasks. Space/view/item state is path-backed so task links survive refresh,
back/forward, and chat sharing. The existing small URL helper is extended; a routing dependency is not
added solely for this feature.
The default Board keeps Monday-like simplicity: inline type-aware add, drag cards, search, assignee/type/tag/release filters, and a details side panel. The panel progressively reveals hierarchy, estimates, dates, typed fields, dependencies, releases, workflow links, pull requests, comments, and activity. List offers dense inline edits and configurable columns. Calendar derives entries from start/due or selected date fields and supports contextual create/date drag. Timeline displays hierarchy, releases, and blocking links; it is read-mostly in the first release, with date-bar movement only after Board/List editing is stable.
Mobile uses a status selector plus cards instead of requiring horizontal drag, List becomes stacked rows, and Calendar defaults to agenda. Every drag action has keyboard buttons/menu equivalents and screen-reader announcements.
Studio follows existing boundaries:
server task route -> OpenAPI -> generated SDK -> api/tasks.ts
-> hooks/tasks/* (React Query) -> TaskWorkspace components
-> existing social WebSocket invalidates workspace-scoped task query keysReuse MarkdownText, WorkspaceAvatar, Dialog primitives, member search, pull request summaries,
workflow selectors, query-key workspace scoping, and safe error patterns. Every new component has a
colocated Storybook story and atomic folder/barrel structure.
Search and performance
Initial task search normalizes item key, title, tags, and searchable text fields and uses a bounded SQLite substring scan within the already-filtered workspace/space set. It returns at most 100 results and never loads all comments or descriptions. Board/List/Backlog queries use indexed keyset pagination; comment and activity streams paginate independently.
ponytail: substring search is the deliberate ceiling. Add a proven full-text index or external
search service only after measured workspace data makes bounded search miss its latency target.
The Studio uses optimistic card movement with rollback on 409, lazy-loads item detail/comments,
and invalidates by Task Space or item key from realtime events. It does not stream entire boards.
Explicit non-goals
- Any dependency on, migration from, integration with, replacement of, or cleanup of
apps/tasks,TASKS.json, orBUGS.json. - Jira-compatible JQL, workflow designers, per-type screens, work-type schemes, field formulas, rollups, plugin-defined field types, or per-space permission schemes.
- Jira Service Management, deployment automation, time sheets, capacity forecasting, burndown reports, forms, SLAs, automation-rule builders, or app marketplace compatibility.
- Multiple active sprints in one Task Space.
- Arbitrary file attachments, email ingestion, or public task sharing.
- Per-Task-Space membership or cross-workspace hierarchy/links.
- Continuous two-way Jira or GitHub Issues synchronization.
- Persisting Board, Calendar, or Timeline membership separately from work items and saved views.
These are extension points, not scaffolding tasks. Add one only when real use demonstrates the need.
Acceptance criteria
- A member can create a simple, Kanban, or Scrum Task Space inside the active workspace and cannot read it from another workspace.
- Users can create Initiative/Epic/Story/Task/Bug/Subtask items only in valid hierarchy relationships. Space managers can add custom types at those fixed levels, and every view can create any valid type inline while inheriting its row/group context.
- Board, List, Calendar, Timeline, Backlog, Active Sprint, My Work, and Initiatives are projections over one item authority and converge after a realtime mutation.
- Card movement is atomic, keyboard accessible, version checked, and rank stable after concurrent edits and a column rebalance.
- A Scrum space can have one active sprint; completion moves incomplete items exactly once to the selected destination.
- Space managers can define tags and bounded typed fields; List columns edit them inline and all supported views filter/group them without accepting arbitrary JSON or SQL.
- Releases show derived work and pull-request progress, appear on Calendar/Timeline, and release unresolved items according to one explicit version-checked choice.
- Comments, activity, assignment, and mentions retain actor identity, version history/tombstones, and workspace notification behavior.
- A work item can link to an accessible Octonode workflow and existing GitHub pull request; stale targets render unavailable without leaking or deleting history.
- Sharing a task link in Chat renders a card only for readers who still have
tasks:read. - Backup, PITR, generation restore, rollback, and workspace deletion include every task table and pass foreign-key/count validation.
- Hosted task list/board routes do not start a Sandbox; workflow/repository operations retain their existing authorities.
- The OpenAPI spec and generated Studio SDK are current, all task components have stories, and the Linux screenshot gate covers populated, empty, loading, error, conflict, archived, and mobile states.
- Product Tasks has no import, runtime, build, UI, or cleanup relationship with
apps/tasks,TASKS.json, orBUGS.json.