# Non-Linear: Data Model ## Overview The data model consists of two overlaid graphs on the same set of nodes: 1. **Decomposition Tree** — strict parent→child hierarchy (DAG) 2. **Association Graph** — lateral many-to-many connections with typed edges These are deliberately separated. The decomposition tree is the *spine* of the product. The association graph is an *overlay* that adds context without defining structure. ## Issue Node (Atomic Unit) Every node in the graph is an **issue**. Issues are intentionally untyped — their depth in the decomposition tree implies their abstraction level. | Field | Type | Description | |-------|------|-------------| | `id` | UUID | Unique identifier | | `title` | string | Short descriptive title | | `description` | text | Detailed description (markdown) | | `status` | enum | Current state (see Status below) | | `labels` | string[] | Freeform tags for orthogonal concerns | | `assignee` | actor_id? | User or agent assigned | | `parent_id` | issue_id? | Parent in decomposition tree (null = root) | | `created_at` | timestamp | Creation time | | `updated_at` | timestamp | Last modification | | `created_by` | actor_id | Creator (user or agent) | ### Status Default statuses (customizable per project): - `backlog` — not yet planned - `todo` — planned, not started - `in_progress` — actively being worked on - `in_review` — awaiting review - `done` — completed - `cancelled` — abandoned ### Labels Labels handle all classification orthogonal to hierarchy: - **Kind:** `bug`, `feature`, `chore`, `spike` - **Area:** `frontend`, `backend`, `infra`, `docs` - **Priority:** `p0`, `p1`, `p2`, `p3` - **Custom:** anything the team defines ### Why Untyped Traditional trackers have explicit types: Epic, Story, Task, Subtask, Bug. This creates rigidity — teams argue about what level something belongs at, and refactoring the hierarchy means changing types. In Non-Linear, depth *is* type: ``` Root (depth 0) → "project level" ├── Child (depth 1) → "component/epic level" │ ├── Child (depth 2) → "feature/story level" │ │ └── Child (depth 3) → "task level" ``` A node's abstraction level is determined by its position, not a type field. Moving a node to a different depth changes its conceptual level automatically. ## Decomposition Tree The decomposition tree is a strict hierarchy with these properties: - **Single parent:** Every node has exactly one parent (except roots) - **Directed:** Edges flow from abstract (parent) to concrete (child) - **Acyclic:** No node can be its own ancestor - **Single root per project:** Each project has one root node (v0.1) ### Reparenting Moving a node to a different parent is a **structural change**. It affects: - The node's implied abstraction level - Agent permissions (if scoped to a subtree) - The layered view layout - Who can access the node (if resource-scoped policies apply) The system should warn when reparenting changes permission boundaries. ## Association Graph (Lateral Links) Lateral links are typed, many-to-many relationships that don't affect hierarchy. ### Link Types | Type | Semantics | Directionality | |------|-----------|----------------| | `blocks` | A blocks B (B can't proceed until A is done) | Directed | | `blocked_by` | Inverse of blocks | Directed (auto-created) | | `relates_to` | General association | Undirected | | `duplicates` | A is a duplicate of B | Directed | ### Cross-Project Links (v0.2+) In future versions, lateral links can cross project boundaries. This enables: - Freelancer's client project depending on a shared library - Shared infrastructure components blocking multiple projects - Cross-team dependency tracking Cross-project links add complexity to permissions (an agent scoped to Project A sees a link to Project B but may not access the target) and are deferred to v0.2. ### Link vs. Parent Relationship | Property | Parent→Child | Lateral Link | |----------|-------------|--------------| | Cardinality | One parent per node | Many-to-many | | Affects hierarchy | Yes | No | | Affects layered view | Yes | Shown as overlay edges | | Affects permissions | Yes (subtree scoping) | No | | Removal impact | Structural (node needs new parent) | Annotation only | ## Project (v0.1) | Field | Type | Description | |-------|------|-------------| | `id` | UUID | Unique identifier | | `name` | string | Project name | | `root_id` | issue_id | Root node of decomposition tree | | `created_at` | timestamp | Creation time | | `members` | actor_id[] | Users and agents with access | In v0.1, each project has exactly one root node and one decomposition tree. Multi-root or cross-project features are deferred.