--- name: graphnet-tracker description: > Convert a goal, project plan, or task description into a GraphLMS **tracker** project in lean JSON v3 format. Outputs a directed task graph: nodes are tasks (with status / deadline / complexity), edges are dependencies, and one or more nodes are marked `isGoal: true` as milestones. The app highlights the longest weighted path to every active goal as a "critical path" so the user can see what stands between them and shipping. Use when the user asks to "сделай план", "разбей задачу на этапы", "составь roadmap", "build me a project plan", "распиши задачу", or hands you a goal to break down. For learning material with quizzes use `graphnet-create`; for a personal knowledge base use `graphnet-wiki`. --- # GraphLMS Content Builder — Tracker Mode Turn a goal or messy project description into a directed task graph that GraphLMS can import as a **tracker** project. The user sees: - Their tasks as nodes coloured by status (todo / in progress / done / blocked / cancelled). - Dependency edges between tasks. - One or more **goal** nodes (milestones) marked with a flag icon. - The **critical path** to every active goal — the longest weighted chain of remaining work — highlighted on the canvas. Move that, and the ship date moves with it. - A sidebar with **active goals** (sorted by deadline) and **active tags** (work streams). Clicking a tag filters the canvas to that slice. > **Project type:** import the produced JSON into a project created with > type **«Трекер»**. The same lean JSON v3 wire format is used as for course > and wiki — but the tracker reads four extra optional per-node fields and > ignores quizzes. ## Mental model A tracker in GraphLMS is **a DAG of tasks aimed at goals**: - A **node** is **one task**. The task has a status, optionally a deadline, optionally a complexity (1..5 effort weight), optionally tags. - An **edge A → B** means *"finish A before B becomes actionable"*. Same prerequisite semantics as `graphnet-create`. The graph **must be a DAG** (no cycles) — if the user describes something cyclic, split it into smaller pieces. - One or more nodes have `isGoal: true`. Goals are the visible "finishes" of the graph. A graph with no goal makes no sense in tracker mode — the whole point is to pull a chain toward a milestone. - **Status** drives node fill colour and weighting: - `todo` (default) — pending, full weight - `in_progress` — currently being worked on - `done` — completed, weight 0 (no longer on the critical path) - `blocked` — visible danger; full weight, but coloured red - `cancelled` — dashed + transparent; weight 0 - **Complexity** (1..5) is the effort weight in the longest-path math. If not set, treated as 1. - **Deadline** drives an urgency chip on the node and ordering of the active-goals sidebar. - **Tags** group nodes into work streams / sub-projects / alternative approaches; clicking a tag filters the canvas to that subgraph. The goal of the skill is to convert intent → a small, well-shaped DAG with a clear goal and reasonable dependencies. Density should reflect actual prerequisites, not aesthetics. ## Output format — lean JSON v3 The same wire format as the course / wiki skills — with four extra optional per-node fields. **Quizzes are ignored on import**, so don't emit them. ### Single graph ```json { "version": 3, "name": "Topic / project name", "defaultLayout": "tree", "nodes": [ /* see below */ ], "edges": [ /* see below */ ] } ``` `defaultLayout` should be `"tree"` for trackers (cleanly shows the dependency hierarchy) — fall back to `"force"` if the graph isn't a clean tree (multiple parents per node). ### Project bundle (multi-graph) ```json { "kind": "project", "version": 2, "name": "Project name", "exportedAt": "2026-04-30T10:00:00Z", "graphs": [ /* lean graph objects */ ] } ``` ### Node — full shape ```json { "id": "deploy-backend", "label": "Развернуть бэкенд", "sections": [ { "type": "text", "markdown": "Описание задачи: ..." } ], "status": "todo", "complexity": 3, "deadline": "2026-06-15", "tags": ["Backend", "Через Stripe"] } ``` ### Node — goal ```json { "id": "ship-mvp", "label": "Запуск MVP", "status": "todo", "isGoal": true, "complexity": 2 } ``` ### Edge ```json { "source": "deploy-backend", "target": "ship-mvp" } ``` Edges are always directed (source → target) and represent *prerequisite* relationships: target depends on source. ## Field rules | Field | Type | Required? | Notes | |---|---|---|---| | `id` | `string` | yes | Stable, ASCII-friendly slug | | `label` | `string` | yes | Russian or whatever language the user used | | `sections` | `[{type:'text', markdown}\|...]` | no | Optional task description | | `status` | enum (5 values) | no, default `'todo'` | See below | | `isGoal` | `boolean` | no, default `false` | At least ONE node MUST have `isGoal: true` | | `deadline` | ISO 8601 date string | no | Only set when the user mentions a date — do NOT invent | | `complexity` | `1 \| 2 \| 3 \| 4 \| 5` | no, treated as 1 if absent | Relative effort vs other nodes in the same graph | | `tags` | `string[]` | no | Plain strings; the app resolves them to per-project Tag entities | **`status` enum:** exactly one of: - `'todo'` — pending - `'in_progress'` — currently active - `'done'` — completed - `'blocked'` — stuck on something external - `'cancelled'` — abandoned Default new graphs to `'todo'` everywhere unless the user explicitly describes some tasks as already done. ## Tag conventions Tags are **opt-in but encouraged** — they're the second axis of organisation after the dependency graph itself. Three useful axes (combine freely): 1. **Work streams (parallel groups):** "Backend", "Frontend", "UX-research", "DevOps". Same general direction, different specialists. 2. **Sub-projects within a goal:** "Авторизация", "Платежи", "Уведомления". Topical clusters around a sub-milestone. 3. **Alternative approaches (forks):** when there's a "or-or" decision — "Через Stripe" / "Через PayPal", or `alt-A` / `alt-B`. Tag both chains; the user can later filter the canvas to "show only path A" or "only path B" to evaluate them side by side. **One node can carry multiple tags from different axes.** A task like "Подключить webhook Stripe" naturally tags as `["Backend", "Через Stripe"]`. **Sweet spot: 5–8 tags per project.** Fewer and the filter loses signal; more and the user can't keep them straight. After the JSON, **always emit a "Suggested tag palette"** block — a list mapping each tag you used to a hex colour the user can paste into the app when they recreate the Tag entities. Same convention as the wiki skill; the JSON itself only carries strings, the colours have to be picked. ``` Suggested tag palette: - Backend — #3B82F6 (синий) - Frontend — #EC4899 (розовый) - Через Stripe — #10B981 (зелёный) - Через PayPal — #F59E0B (оранжевый) ``` Match colours to semantics (warm for "fast/critical", cool for "foundational"). Different alternatives should have **distinct hues** so the filter chip is unambiguous. ## Goal placement - **Always include at least one goal node** (`isGoal: true`). - The goal is usually the **last node** in the chain (no outgoing edges, many incoming) — but a graph can have multiple goals if the user is working toward several milestones. - Mark the **end state**, not "do everything". "Запуск MVP" beats "Стать миллионером". - A goal node can carry its own complexity (small — usually 1–2) for the "sign off" / "release" / "publish" act itself. ## Edge rules - **DAG only.** No cycles. If the user describes something circular, split it: most "circular" descriptions are actually iterations of a smaller task ("Refactor X" → "Pass A" → "Pass B" → "Final pass"). - **Prerequisite, not "anything related".** If A doesn't strictly need to be done before B, don't connect them. Wiki nodes connect promiscuously; tracker nodes do not. - **Multiple parents are fine.** "Запуск MVP" can depend on "Backend готов", "UI готов", "Маркетинг готов" all at once. The critical path math handles parallel chains correctly. - **Alternative chains are encouraged.** Two paths to the same goal — e.g. through Stripe vs through PayPal — model real "or" decisions and light up cleanly with the tag filter. ## Sizing and density - **5–25 nodes is the sweet spot.** Below 5, the graph form adds nothing over a checklist. Above 25, the user can't hold the graph in their head; split into multiple graphs (a project bundle) by sub-goal. - Each node is **one actionable task**, not "a phase". "Phase 1" is a bad node; "Развернуть бэкенд", "Протестировать платежи", "Согласовать макеты" are good nodes — concrete, completable, claimable as done. - If something is fuzzy ("исследовать рынок"), make it concrete enough to end. ("Опросить 5 потенциальных клиентов", complexity 2.) ## Worked example User: *"Сделай мне трекер для запуска подкаста с двумя вариантами монетизации — реклама или Patreon, с дедлайном к концу июня."* ```json { "version": 3, "name": "Запуск подкаста", "defaultLayout": "tree", "nodes": [ { "id": "concept", "label": "Сформулировать концепцию", "status": "todo", "complexity": 2, "tags": ["Контент"] }, { "id": "pilot-script", "label": "Написать сценарий пилота", "status": "todo", "complexity": 3, "tags": ["Контент"] }, { "id": "record-pilot", "label": "Записать пилот", "status": "todo", "complexity": 4, "tags": ["Контент", "Продакшн"] }, { "id": "edit-pilot", "label": "Смонтировать пилот", "status": "todo", "complexity": 3, "tags": ["Продакшн"] }, { "id": "branding", "label": "Заказать обложку и бренд", "status": "todo", "complexity": 2, "tags": ["Маркетинг"] }, { "id": "platforms", "label": "Опубликовать на платформах", "status": "todo", "complexity": 2, "tags": ["Маркетинг", "Продакшн"] }, { "id": "ad-research", "label": "Прайс-лист рекламы", "status": "todo", "complexity": 2, "tags": ["Реклама"] }, { "id": "ad-pitch", "label": "Связаться с 3 рекламодателями", "status": "todo", "complexity": 3, "tags": ["Реклама"] }, { "id": "patreon-setup", "label": "Настроить Patreon-страницу", "status": "todo", "complexity": 2, "tags": ["Patreon"] }, { "id": "patreon-tiers", "label": "Описать тиры и бонусы", "status": "todo", "complexity": 2, "tags": ["Patreon"] }, { "id": "launch", "label": "Запуск подкаста", "status": "todo", "isGoal": true, "complexity": 1, "deadline": "2026-06-30", "tags": ["Маркетинг"] } ], "edges": [ { "source": "concept", "target": "pilot-script" }, { "source": "pilot-script", "target": "record-pilot" }, { "source": "record-pilot", "target": "edit-pilot" }, { "source": "edit-pilot", "target": "platforms" }, { "source": "branding", "target": "platforms" }, { "source": "platforms", "target": "launch" }, { "source": "ad-research", "target": "ad-pitch" }, { "source": "ad-pitch", "target": "launch" }, { "source": "patreon-setup", "target": "patreon-tiers" }, { "source": "patreon-tiers", "target": "launch" } ] } ``` ``` Suggested tag palette: - Контент — #3B82F6 (синий) - Продакшн — #6366F1 (индиго) - Маркетинг — #EC4899 (розовый) - Реклама — #F59E0B (оранжевый) - Patreon — #10B981 (зелёный) ``` The user can now: - See the whole plan as a graph with `Запуск подкаста` flagged as the goal. - See the longest chain (концепция → сценарий → запись → монтаж → публикация → запуск) as the critical path. - Filter by `Реклама` to evaluate the ad-monetisation branch in isolation. - Filter by `Patreon` to evaluate the alternative. - Pick the branch they like and cancel the other (set those nodes `cancelled` — they fade and stop counting toward the critical path). ## Import flow 1. Tell the user what the graph looks like (1–2 sentences). 2. Emit the **JSON block** — pure JSON, no markdown decoration inside. 3. Emit the **Suggested tag palette** block. 4. Tell the user how to import: - In the Rhizome LMS web app: create a project of type **«Трекер»**, open it, and use **«Импорт JSON»** in the project settings panel. - Or via Claude with the `rhizome-lms-mcp` MCP server (v0.3.0+): `create_project` with `projectType: "tracker"`, then `create_graph` with the JSON. 5. Remind them to recreate the Tag entities in the UI with the suggested colours so the filter chips render correctly (known limitation of v3 lean JSON — tags are emitted as strings, the per-project Tag entities have to be created in the app). ## Anti-patterns to avoid - **No goal node** — fail the request, ask the user what the milestone is. - **Inventing deadlines** — only use deadlines the user actually mentioned. Better to leave it off than guess. - **Cycles in the graph** — split iterative work into discrete passes. - **Vague nodes ("Phase 1", "Research")** — push for one concrete completable task per node. - **All nodes connected to all** — a tracker isn't a wiki. Edges are prerequisites, not "related to". - **Pre-cancelling alternatives** — leave both forks active with status `todo`; let the user explore both before committing. Don't pick for them. - **Ignoring tags** — even a 5-node tracker benefits from tags when there are parallel work streams. Don't skip them just because the graph is small. ## When the user gives you partial info - **No deadline given:** omit the `deadline` field entirely on every node. - **No complexity hints:** infer relative weights from the descriptions (e.g. "написать черновик" — 2, "переписать с нуля" — 4, "согласовать" — 1). Be consistent within the graph. - **Goal not obvious:** ask one targeted question ("Что считаем успешным результатом? Запуск версии 1.0? Первая выручка? Сдача отчёта?") and wait. Don't guess the goal — that's the most important node. - **Status not specified:** everything is `todo`. Don't pre-mark anything `done`.