К основному содержанию
скилл CX Codex

cycle-render — скилл для Claude Code: визуализация циклов и установка

Преобразует историю циклов из YAML в диаграмму Ганта и распределение результатов. Помогает просмотреть циклы и отфильтровать их по дате или классу.

Установить в Claude Code · Через Skills CLI (Vercel) Все способы и платформы ↓
npx skills add haabe/mycelium --skill cycle-render -a claude-code
Открыть на GitHub

Что делает cycle-render

Скилл читает .claude/canvas/cycle-history.yml и строит диаграмму Ганта, круговую диаграмму результатов или обе сразу. Можно выбрать вывод Mermaid, ASCII или JSON, задать дату начала периода и класс цикла. Данные он только отображает: записывать итоги нужно другими командами Mycelium.

Перед рендером скилл сверяет имена и упоминания с реестром атрибуции: сначала проверяет $MYCELIUM_ATTRIBUTION_REGISTRY, затем .claude/memory/attribution-registry.yml. По настройке согласия имена могут отображаться буквально или заменяться анонимными метками; параметр --no-identifiers скрывает все имена. Для внешней аудитории отсутствие реестра блокирует вывод, поэтому перед таким запуском проверьте его наличие.

Какие задачи решает

  • показать историю циклов на диаграмме Ганта
  • сравнить распределение результатов циклов
  • отфильтровать циклы по дате начала
  • отобразить циклы выбранного класса
  • скрыть имена участников при рендере

Примеры запросов агенту

  • Покажи историю циклов из .claude/canvas/cycle-history.yml в Mermaid.
  • Выведи только диаграмму Ганта для циклов после 2025-01-01 в формате ASCII.
  • Собери JSON по циклам класса observation и скрой все имена.

Как установить cycle-render

1Через Skills CLI (Vercel)

npx skills add haabe/mycelium --skill cycle-render -a claude-code

2Вручную: положить файлы

~/.claude/skills/cycle-render/SKILL.md

Папка скилла целиком; для одного проекта — .claude/skills/cycle-render/

По шагам, с командами для каждой платформы: Как установить скилл в Claude Code: пять способов

Вопросы о cycle-render

Как установить cycle-render в Claude Code?

Выполните npx skills add haabe/mycelium --skill cycle-render -a claude-code. Файл скилла будет доступен по пути ~/.claude/skills/cycle-render/SKILL.md.

Что делает cycle-render?

Читает историю циклов и отображает её как диаграмму Ганта, распределение результатов или JSON, с фильтрами по дате и классу цикла.

Что происходит, если реестр атрибуции недоступен?

Для внешней аудитории рендер блокируется. В остальных описанных случаях скилл выводит предупреждение и считает результат предназначенным для внутреннего использования.

Исходный текст

SKILL.md · MIT
---
name: cycle-render
description: Render `.claude/canvas/cycle-history.yml` as a Gantt chart + outcome distribution pie (or ascii / json). Read-only. Consults the attribution registry per `${CLAUDE_PLUGIN_ROOT}/engine/render-conventions.md` consent + privacy gate. Third specialist in the render fleet.
metadata:
  instruction_budget: "55"
  framework_dependency: "mycelium"
  framework_dependency_note: "Reads .claude/canvas/cycle-history.yml + attribution registry (env var $MYCELIUM_ATTRIBUTION_REGISTRY preferred; .claude/memory/attribution-registry.yml fallback)."
  identifier_exposure: "YES"
---

# Cycle Render

Read-only render of `.claude/canvas/cycle-history.yml` as gantt + pie + (optionally) json. Third specialist in the render fleet. See `${CLAUDE_PLUGIN_ROOT}/engine/render-conventions.md` for shared conventions.

## When NOT to use

- For cross-cutting opportunity→solution→cycle traceability view → dispatcher's `/mycelium:render --view traceability` (deferred to Phase 4a–4d research-first methodology).
- To RECORD a new cycle outcome → `/mycelium:retrospective`, `/mycelium:ice-score` (on discard), or `/mycelium:launch-tier` (on launch). This skill is read-only.
- For framework-health full assessment → `/mycelium:framework-health`. cycle-render emits one visualization piece; framework-health is the broader audit.

## Identifier exposure

**Declared**: YES

### Scope (canvas surfaces touched)

| Canvas file | Identifier-bearing fields | Frequency |
|---|---|---|
| `.claude/canvas/cycle-history.yml` | `learnings.process` prose; `learnings.framework` prose; `related_corrections` references | mid (cohort-related observation cycles directly reference participants) |
| `$MYCELIUM_ATTRIBUTION_REGISTRY` env var (canonical) or `.claude/memory/attribution-registry.yml` (fallback) | `people:` block with `name`+`consent`+`note` per entry | read-only consultation; never rendered |

### Rationale

Cycle history is reflection-shaped: `learnings.process` is prose-heavy and often names testers whose feedback drove the cycle (e.g., a cycle entry with `leaf_id: ht-014-alex-first-week-observation` carries an identifier in the leaf_id itself). Identifier exposure is structural to the learnings narrative, not incidental. Consent state for named cohort testers can shift over time per the consent-state-change-skip cluster (anti-pattern #7 sub-shape #15) — cycle-render re-consults the registry on every invocation, never caches.

### Anon-label convention

Per `engine/render-conventions.md#anon-label-convention`. Numbering shared across the render-fleet session (cohort-tester-N in cycle-003 IS cohort-tester-N in opp-004 evidence if both rendered in one session).

In gantt output, anon labels appear in `section` names and task IDs. In ascii output, in chronological listings. In json output, in `learnings_process` strings AND a parallel `identifier_map` field for auditability.

### Consent value semantics

Per `engine/render-conventions.md#consent-value-semantics`. `public_ok` → render literal + carve-out footnote pointer if entry has non-empty `note:`. `generic_only` → redact to anon-label. `unknown` → treat as `generic_only`. Not-in-registry → fail loud unless `--no-identifiers=true`.

### Worked examples

**public_ok cohort tester → literal**: cycle entry with leaf_id `ht-014-alex-first-week-observation`, registry entry `{name: "Alex", consent: public_ok, note: "..."}` → gantt section reads `Alex first-week observation` + carve-out footnote pointer.

**generic_only → anon-label**: a future cycle naming "Random Tester" with registry `consent: generic_only` → gantt section reads `cohort-tester-N first-week observation` + anon-mapping footnote.

**Maintainer literal**: a cycle prose mentions "Håvard's Torres-shape question", registry `{name: "Håvard", consent: public_ok}` → renders literally.

**Identifier not in registry → fail loud**: a future cycle adds a tester never registered → fail-loud per `engine/render-conventions.md`. The upstream fix is in `/mycelium:retrospective` (consult registry on cycle recording); cycle-render is the downstream gate.

### Fixture pointer

- `tests/bash/fixtures/cycle-render/redaction-public-ok-literal-gantt.yml`
- `tests/bash/fixtures/cycle-render/redaction-generic-only-anon-gantt.yml`
- `tests/bash/fixtures/cycle-render/redaction-public-maintainer.yml`
- `tests/bash/fixtures/cycle-render/redaction-no-registry-entry-fail-loud.yml`
- `tests/bash/fixtures/cycle-render/redaction-carve-out-note-footnote.yml`

## Preflight: Read sources

1. Read `.claude/canvas/cycle-history.yml` with the Read tool. Full read; not `limit:1`.
2. Read the attribution registry per path resolution order in `engine/render-conventions.md#registry-path-resolution`: `$MYCELIUM_ATTRIBUTION_REGISTRY` env var first; fall back to `.claude/memory/attribution-registry.yml`. If registry absent, surface a `⚠ no attribution-registry — consent-redaction not enforceable; treat output as roadmap-internal` warning in the render header. **For `--audience external`, an absent registry BLOCKS the render and emits no artifact** (v0.173.0) — same outcome as an unregistered identifier, because an absent registry is that same unresolved-consent condition applied to every identifier at once. The warning-and-emit path is for `founder`/`cohort` only.
3. Note canvas-state timestamp per `engine/render-conventions.md#canvas-state-timestamp-resolution`: `_meta.last_validated` if present; fall back to top-level `last_updated:`.

## Arguments

| Arg | Default | Values | Effect |
|---|---|---|---|
| `--format` | `mermaid` | `mermaid` \| `ascii` \| `json` | Output format. `markdown-table` and `markdown-list` are NOT supported (gantt doesn't map cleanly); fail loud per `engine/render-conventions.md#format-support-negotiation-global-rule`. |
| `--view` | `both` | `gantt` \| `pie` \| `both` | Which diagram(s) to emit. |
| `--theme` | `base` | `base` \| `dark` | Theme. `dark` is the WCAG-by-construction opt-in per `engine/render-conventions.md#wcag-aa-theme-convention`. |
| `--since` | `null` | ISO date | Filter cycles whose `started_at` is on or after this date. |
| `--cycle-class` | `all` | `product-leaf` \| `meta-dogfood` \| `observation` \| `all` | Filter by cycle_class field. |
| `--no-identifiers` | `false` | bool | Force all name references to redact regardless of consent state. |

## Workflow

### Step 1: Parse + filter

Read cycles array. Apply `--since` and `--cycle-class` filters. Sort by `started_at`. If filtered set is empty:
- For `--cycle-class product-leaf` with 0 matches: emit honest-dark-data placeholder (`No product-leaf cycles in window — meta-dogfood and observation cycles are filtered out per --cycle-class. Total cycles in scope: N`).
- For all other empty cases: emit placeholder + pointer to `/mycelium:retrospective`.

### Step 2: Consent check on identifier-bearing fields

Per `engine/render-conventions.md#hard-rule-consent--privacy-gate`. For every `learnings.process`, `learnings.framework`, `related_corrections`, AND every `leaf_id` token that may contain an identifier:
- Skip URL-shaped and file-path-shaped entries.
- Skip already-anon canvas labels.
- For name-shaped remaining entries: look up first-name token in `people:`.
- Apply consent semantics per the engine doc table.
- Maintain consistent anon-label numbering (same registry entry → same N) shared with concurrent renders.

### Step 3: Staleness vs pending-retrospective check

Per `engine/render-conventions.md#staleness-check-distinction`:

- **Canvas-stale**: cycle data drifted from decision-log entries → use `⚠ STALE` shape.
- **Pending-retrospective**: decision-log has substantive work since the most-recent cycle's `completed_at` BUT no cycle entry yet → use `ℹ Pending retrospective` shape. Render proceeds normally; informational not error.

### Step 4: Build gantt model (if `--view gantt|both`)

Per cycle in filtered set:
- Section = cycle's cycle_class (`meta-dogfood`, `observation`, `product-leaf`).
- Task ID = cycle's cycle_id (e.g., `c001` from `cycle-001`).
- Task label = short title (truncated to ~40 chars per `engine/render-conventions.md#mermaid-label-escape-rules`).
- Start = `started_at`.
- Duration = `completed_at` minus `started_at` (default 1d if missing).
- Status class (Mermaid gantt status keyword):
  - `done` for `actual.outcome: success` AND `terminal_state: launched`
  - `active` for in-progress (no `completed_at`)
  - `crit` for `actual.outcome: failure` OR `terminal_state: killed`

### Step 5: Build pie model (if `--view pie|both`)

Sum `actual.outcome` distribution across the filtered set: success / partial / failure / archived / killed (per `terminal_state` fallback when `actual.outcome` absent). Honest small-N display: if total <5, prepend a header note `Note: N=<total>; distribution shape may not be load-bearing at this sample size`.

### Step 6: Emit by format

**Format `mermaid` (default)** — gantt + pie with WCAG AA themes.

Use **frontmatter config syntax** per `engine/render-conventions.md#mermaid-frontmatter-syntax-preferred`. `--theme dark` opt-in.

```mermaid
---
config:
  theme: base
  themeVariables:
    sectionBkgColor: '#f5f5f5'
    altSectionBkgColor: '#e8f5e9'
    gridColor: '#666666'
    doneTaskBkgColor: '#a5d6a7'
    doneTaskBorderColor: '#1b5e20'
    activeTaskBkgColor: '#90caf9'
    activeTaskBorderColor: '#0d47a1'
    critBkgColor: '#ef9a9a'
    critBorderColor: '#b71c1c'
    taskTextColor: '#1a1a1a'
    taskTextDarkColor: '#1a1a1a'
    taskTextOutsideColor: '#1a1a1a'
    taskTextLightColor: '#1a1a1a'
    titleColor: '#1a1a1a'
---
gantt
  title Cycle History (filtered N=<count>)
  dateFormat YYYY-MM-DD
  section meta-dogfood
    cycle-001 ruff/coverage cleanup :done, c001, 2026-05-03, 1d
    cycle-002 AP#7 enforcement       :done, c002, 2026-05-09, 1d
  section observation
    cycle-003 first-week observation :done, c003, 2026-05-14, 11d
```

```mermaid
---
config:
  theme: base
  themeVariables:
    pie1: '#a5d6a7'
    pie2: '#fff59d'
    pie3: '#ef9a9a'
    pieTitleTextColor: '#1a1a1a'
    pieSectionTextColor: '#1a1a1a'
    pieLegendTextColor: '#1a1a1a'
    pieStrokeColor: '#333333'
    pieOuterStrokeColor: '#333333'
---
pie title Outcome distribution
  "success" : 5
  "partial" : 3
  "failure" : 0
```

**Status-color semantics warning**: Mermaid gantt `:crit` defaults to red, which reads as "failure" to viewers unfamiliar with the syntax. Cycle outcomes use a different ontology (success/partial/failure based on `actual.outcome`). The `:crit` color is currently reused for `actual.outcome: failure` AND `terminal_state: killed`; a `--status-mapping <strict|loose>` future arg could disambiguate (open implementation question).

**Format `ascii`** — terminal-friendly:

```
Cycle History (filtered N=8, 2026-05-03 to 2026-06-05)
═══════════════════════════════════════════════════════════

meta-dogfood (7)
  cycle-001 ruff/coverage cleanup        2026-05-03  [done]
  cycle-002 AP#7 enforcement             2026-05-09  [done]
  cycle-004 opp-007 tech-discovery       2026-05-31  [partial]
  ...

observation (1)
  cycle-003 first-week observation       2026-05-14  [done] 11d

Outcome distribution:
  success: ████████████        5
  partial: ████████            3
  failure: (none)              0
```

**Format `json`** — external-system integration:

```json
{
  "schema_version": 1,
  "render": "cycle",
  "source": ".claude/canvas/cycle-history.yml",
  "source_last_validated": "<YYYY-MM-DD>",
  "filter": {"since": null, "cycle_class": "all"},
  "cycles": [
    {
      "cycle_id": "cycle-001",
      "cycle_class": "meta-dogfood",
      "started_at": "2026-05-03T20:00:00Z",
      "completed_at": "2026-05-03T22:00:00Z",
      "terminal_state": "launched",
      "outcome": "success",
      "label": "ruff/coverage cleanup"
    }
  ],
  "distribution": {"success": 5, "partial": 3, "failure": 0},
  "identifier_map": {},
  "dropped_fields": ["predicted", "actual.user_metrics", "calibration", "learnings", "deliverables", "related_corrections"]
}
```

### Step 6b: Validate the emitted Mermaid (MANDATORY for `mermaid` format)

Pipe each block you just emitted (gantt and/or pie) through the static validator before showing it:

```bash
printf '%s' "$DIAGRAM" | python3 ${CLAUDE_PLUGIN_ROOT}/scripts/validate_mermaid.py -
```

It checks the two things you cannot check by eye: **state-id consistency** (F11) and **WCAG AA contrast** of every `themeVariables` foreground/background pair (F13, ≥ 4.5:1). This skill carries two `themeVariables` blocks (gantt + pie), so validate both. Add `--cli` to also shell out to `mmdc` for a full parse when present (fail-open when absent).

Exit 1 means at least one FAIL: **fix the diagram and re-validate before emitting.** Do not show the user a diagram that failed this check.

Visual layout and communicative quality remain operator-side — hence the Step 7 disclaimer. This step covers only what is mechanically decidable. (Wired 2026-07-26: the validator shipped with a coverage proof but no render skill invoked it.)

### Step 7: Append disclaimers

Per `engine/render-conventions.md`:

- **Class-distribution disclosure** in gantt header (e.g., `7 meta-dogfood + 1 observation + 0 product-leaf`). Honest dark-data on `product-leaf: 0` is the canonical case for early-stage dogfood projects.
- **Lossy-on-export**: list dropped fields. For cycle-render: `predicted.ice_score`, `predicted.feasibility_risk`, `actual.user_metrics`, `actual.dora_metrics`, `calibration`, full `learnings` prose, `deliverables`, `related_corrections`.
- **Redaction footnote** if anon-labels emitted: list anon-label → registry-entry mapping for audit.
- **Carve-out footnote pointers** for any literal name whose registry entry has non-empty `note:`.
- **Canonical disclaimer**: final block.
- **mermaidchart.com handoff** for `--format mermaid` only.

## Rules

1. **Read-only.** Never modify cycle-history.yml or any state.
2. **Default `--view both`.** Emit pie even when small N — honest "5/3/0" is load-bearing even when the chart looks sparse. Small-N header note required at N<5.
3. **If cycle-history.yml has 0 cycles**, emit placeholder + pointer to `/mycelium:retrospective`. Do NOT error.
4. **Cycle-class filter with 0 matches**: emit honest-dark-data placeholder, not an empty diagram.
5. **Never invent** cycles, outcomes, or learnings not in the canvas.
6. **Consent gate non-skippable** unless `--no-identifiers=true`.

## Counter-Argument Check

Before emitting:

1. *"Am I making a 5-success / 3-partial / 0-failure split look healthier than the meta-dogfood-vs-product-leaf class distribution warrants?"* Class distribution in header surfaces `0 product-leaf` as honest dark data, not a clean record.
2. *"Did I consult the registry for every name in `learnings.process` prose AND in leaf_id tokens, not just the obvious ones?"* The fraud risk lives in maintainer names that may or may not be in the registry depending on consent state at recording time.
3. *"Did I distinguish staleness from pending-retrospective?"* Decision-log activity newer than the most-recent cycle's `completed_at` is informational, not an error.

## What this skill does NOT do

- Does NOT record new cycles. That's `/mycelium:retrospective`.
- Does NOT compute calibration aggregates. That's `/mycelium:framework-health`.
- Does NOT cross-cut to opportunities/solutions. That's the dispatcher's `--view traceability` (deferred).

## Test fixtures (G-V12 / Check 37)

- `tests/bash/fixtures/cycle-render/empty-history.yml` → assert placeholder
- `tests/bash/fixtures/cycle-render/single-cycle.yml` → assert gantt + pie with 1 entry
- `tests/bash/fixtures/cycle-render/since-filter.yml` → assert `--since 2026-06-01` excludes earlier
- `tests/bash/fixtures/cycle-render/cycle-class-filter.yml` → assert `--cycle-class product-leaf` returns honest-dark placeholder when N=0
- `tests/bash/fixtures/cycle-render/view-pie-only.yml` → assert `--view pie` does not emit gantt
- `tests/bash/fixtures/cycle-render/pending-retrospective.yml` → assert informational `ℹ Pending retrospective` shape
- `tests/bash/fixtures/cycle-render/canvas-stale.yml` → assert `⚠ STALE` shape
- `tests/bash/fixtures/cycle-render/redaction-public-ok-literal-gantt.yml`
- `tests/bash/fixtures/cycle-render/redaction-generic-only-anon-gantt.yml`
- `tests/bash/fixtures/cycle-render/redaction-no-registry-entry-fail-loud.yml`

## Theory citations

- Forsgren (DORA — `cycle_class: product-leaf` cycles inform delivery metrics)
- Argyris (double-loop — cycle learnings are the loop's structured output)
- Goodhart (counter-metric discipline — pie's honest dark-data is the anti-Goodhart move)
- WCAG 2.1 AA (gantt + pie color palette per `engine/render-conventions.md#wcag-aa-theme-convention`)

© haabe · MIT · haabe/mycelium

Похожие скиллы

Все скиллы по теме «Настройка агента: память, контекст, субагенты» →
setup-matt-pocock-skills Matt Pocock Скилл настраивает репозиторий для инженерных скиллов Matt Pocock: задаёт трекер задач, метки триажа и расположение доменной документации. Запустите его перед первым использованием остальных скиллов. 1 052 851установок ask-matt Matt Pocock Помогает выбрать подходящий скилл или рабочий поток из набора Matt Pocock. Пригодится, когда непонятно, с чего начать задачу: от идеи до разбора бага. 766 587установок to-tickets Matt Pocock Разбивает план, спецификацию или переписку на небольшие сквозные задачи и отмечает, какие из них блокируют остальные. Пригодится, когда нужно согласовать порядок работы до публикации задач в трекере. 711 230установок writing-plans Jesse Vincent Скилл превращает требования к многошаговой задаче в подробный план реализации до начала работы с кодом. Пригодится, когда исполнителю нужно зафиксировать файлы, интерфейсы и проверки. CX Codex 282 859установок caveman-review JuliusBrussee Пишет замечания к коду одной строкой: место, проблема, исправление. Пригодится, когда ревью диффа или PR надо пройти быстро и без воды. CX Codex +1 411 800установок caveman-compress JuliusBrussee Сжимает CLAUDE.md, списки задач и другие текстовые файлы в краткий формат, сохраняя читаемую резервную копию. CX Codex +1 411 500установок

Из того же набора58

delivery-bootstrap Определяет стек и окружение в незнакомом репозитории, проверяет сборку и тесты, а затем предлагает подходящие инструменты безопасности. CX Codex +1 ★ 47звёзд репо definition-of-done Сверяет критерии готовности задачи с проверяемыми результатами: файлами, выводом команд и тестами. Помогает не закрыть задачу только на основании уверенного отчёта агента. CX Codex +1 ★ 47звёзд репо define-done Фиксирует Definition of Done для «диамонда» — не список задач, а изменение поведения, которое создаёт ценность. Пригодится, когда проект закрывают по факту выката фичи, а не по результату. CX Codex +1 ★ 47звёзд репо cynefin-classify Классифицирует задачу по модели Cynefin на пять доменов и подбирает подходы к её решению. Работает внутри фреймворка Mycelium. CX Codex +1 ★ 47звёзд репо count Считает по вашему репозиторию одну строку: когда появился первый файл кода, сколько решений принято до него, сколько сессий. Никуда ничего не отправляет. CX Codex +1 ★ 47звёзд репо corrections-audit Разбирает журнал правок, находит повторяющиеся ошибки агента и переводит их в правила-ограничители. CX Codex +1 ★ 47звёзд репо canvas-update Скилл обновляет файлы канваса по новым свидетельствам, проверяет связанные разделы и записывает изменения в журнал. Работает в проектах на Mycelium. CX Codex +1 ★ 47звёзд репо canvas-sync Скилл тянет и коммитит состояние канвы через git, чтобы у всех в команде была одна версия продуктовых знаний. Ставится на старте и в конце сессии. CX Codex +1 ★ 47звёзд репо

Спонсоры проекта

Компании, которые помогают держать аналитику открытой