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

canvas-health — скилл для Claude Code: что делает и как установить

Проверяет базу знаний canvas на устаревание данных, пропуски полей и противоречия в оценках уверенности. Помогает держать контекст агента в чистоте.

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

Что делает canvas-health

Скилл проводит аудит файлов canvas в проектах на базе Mycelium. Сначала он сверяет список обязательных документов с конфигурацией в .claude/diamonds/active.yml и правилами из canvas-guidance.yml. Пустые файлы или заготовки размером до 50 байт сразу попадают в отчёт об ошибках.

Дальше инструмент анализирует блок _meta и сроки валидации сведений по категориям: от 30 дней для метрик поставки до 365 дней для регуляторных требований. Он отслеживает несоответствия в оценке уверенности. Если показатель превышает 0.5 при статусе гипотезы или 0.7 при одном источнике данных, скилл выдаст предупреждение. Текстовое обоснование рядом с числом тоже проверяется. Расхождение между цифрой в поле и объяснением в прозе будет помечено как ошибка. Такие расхождения искажают контекст модели.

Скилл рассчитан на фреймворк Mycelium, поэтому в изоляции он пропускает проверку состояний и внутренних шлюзов. Прогон полезно делать перед фиксацией решений или после недели простоя репозитория.

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

  • найти устаревшие файлы базы знаний canvas
  • выявить расхождения между числовой уверенностью и текстовым обоснованием
  • проверить наличие обязательных файлов проекта по схеме Mycelium
  • отследить неподтверждённые гипотезы с завышенным уровнем достоверности

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

  • Проверь актуальность файлов canvas через canvas-health
  • Запусти аудит базы знаний canvas перед принятием решения
  • Найди устаревшие метрики и неподтверждённые предположения в canvas

Как установить canvas-health

1Через Skills CLI (Vercel)

npx skills add haabe/mycelium --skill canvas-health -a claude-code

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

~/.claude/skills/canvas-health/SKILL.md

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

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

Вопросы о canvas-health

Как установить canvas-health в Claude Code?

Выполните команду в терминале: npx skills add haabe/mycelium --skill canvas-health -a claude-code.

Что делает canvas-health?

Скилл проверяет файлы базы знаний canvas на полноту, просроченные даты валидации, корректность типов доказательств и совпадение числовых оценок с их описанием.

Нужен ли фреймворк Mycelium для запуска canvas-health?

Да, скилл спроектирован для работы внутри Mycelium. При автономном запуске без окружения фреймворка он пропустит проверку состояния холста и внутренние логические шлюзы.

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

SKILL.md · MIT
---
name: canvas-health
description: "Lint canvas files for staleness, missing fields, inconsistent evidence types, and orphaned references. Run periodically or before major transitions."
metadata:
  instruction_budget: "87"
  framework_dependency: "mycelium"
  framework_dependency_note: "This skill is designed to run within the Mycelium framework (https://github.com/haabe/mycelium). Standalone use will skip the canvas state, theory gates, and harness behavior the skill assumes. Install: /plugin install mycelium@haabe-mycelium."
---

# Canvas Health Check

Audit the canvas knowledge base for quality, consistency, and completeness. The canvas is Mycelium's source of truth -- its quality directly determines agent output quality (Raschka: "context quality = model quality").

## When to Use

- Before any diamond records a decision (called automatically by `/mycelium:diamond-assess`)
- After a period of inactivity (>7 days since last canvas update)
- When agent output quality seems to degrade
- After onboarding a new team member (ensures canvas is self-explanatory)
- Proactively: run periodically to catch silent drift

## Workflow

1. **Load project configuration**:
   - Read `.claude/diamonds/active.yml` for `product_type` and `project_type`
   - Read `${CLAUDE_PLUGIN_ROOT}/engine/canvas-guidance.yml` for required/recommended/optional files per project type

2. **Check file presence**:
   - For each **required** canvas file: does it exist? Is it non-empty (>50 bytes)?
   - For each **recommended** canvas file: does it exist? Flag as gap if missing.
   - Report: `N/M required files present, K recommended files missing`

3. **Check `_meta` blocks**:
   - For each existing canvas file, check for `_meta:` block
   - Flag missing `_meta` blocks
   - Flag `last_validated` past **the horizon for that file's category**, per the
     "Which threshold applies to which canvas file" table in
     `${CLAUDE_PLUGIN_ROOT}/engine/evidence-decay.md` (strategic 180d, technical
     feasibility 120d, user-needs/competitive/market 90d, delivery metrics 30d,
     regulatory 365d; unlisted files fall back to 90d).
   - **SKIP any file whose `_meta.applicability` marks it inapplicable** (a value
     starting `n/a`, or naming a product type this project is not, or saying "NOT
     actively used", **or declaring the file an append-only log with no quality bar to
     validate against**). Added v0.90.0; the append-only form added v0.234.0.
     **WHY THE APPEND-ONLY FORM WAS MISSING FOR SO LONG, AND WHY IT IS THE SAME RULE.**
     Step 9b below already exempts append-only logs from its length budget, on the
     reasoning that for such a file the line count IS the value and pages-as-shape is a
     category error. **The identical reasoning applies to a validation DATE on a file
     with nothing to validate**, and this step never got the rule — so a dogfood
     `archived-solutions.yml`, a registry of discarded leaves whose own `_meta` said
     "no quality bar to validate against", was flagged as stale on every pass. Its author
     had written the exemption in prose AND appended "flagged as missing `_meta` in
     recurring canvas-health passes" to the marker, and it went on being flagged: **a
     finding the author has pre-emptively annotated as noise is a check being routed
     around**, which is the condition this very step warns trains a reader to skip it
     (2026-09-21). Same one-rule-two-places shape as the horizon exemption written into
     8c(b) and not carried to 8c(a). Two dogfood canvases held ZERO evidence — every
     metric field null, the only non-null leaves `False` schema defaults — and already
     said so in their own `_meta`. They decayed on a 30-day horizon anyway, and the only
     way to silence that warning would have been to date a validation of a file nobody
     uses: the manufactured-validation move v0.89.0 removed `last_updated` to prevent.
     Precedents for the marker: `dora-metrics.yml#sre` (`n/a-until-production`) and
     `dependency-pins.yml` (`scope: local`).
     **This replaced a flat 30-day rule in v0.89.0.** That rule was the only
     staleness number in this skill grounded in nothing — step 7 below has always
     used the decay table — and on the dogfood repo it flagged 20 of 25 canvases,
     including a strategic file validated 46 days earlier against a 180-day
     horizon. A check that fires on 80% of a corpus trains its reader to skip it.
   - Flag `version` field missing or at 0

4. **Check confidence consistency**:
   - Gather all `confidence:` values across canvas files
   - Flag confidence > 0.5 with `evidence_type: speculation` or `evidence_type: assumption`
   - Flag confidence > 0.7 with fewer than 2 evidence sources
   - Flag confidence values that haven't changed across git history (anchored confidence anti-pattern)
   - Cross-check against `.claude/diamonds/active.yml` confidence
   - **Cross-check the confidence RATIONALE prose too, not only the `confidence:` field.** Projects record *why* a value moved in narrative fields (`confidence_effect`, `confidence_effect_v2`, or any prose block that names a number). Nothing reads those, so a canvas can be numerically consistent everywhere while the sentence explaining the number contradicts it. Flag when a rationale block names a confidence value that no longer matches `.claude/diamonds/active.yml`. **Prose that encodes state is state, and it is otherwise unvalidated.** (Roadmap dogfood 2026-08-02: the field said 0.10, the narrative beside it still said 0.25, and the numeric check passed.)

5. **Check evidence type consistency**:
   - Every canvas file with `evidence_type:` should have it set to one of the shipped schema enum values (`schemas/canvas/_common.schema.json#$defs/evidence_type` — Gilad's evidence ladder): `speculation`, `anecdotal`, `data-supported`, `test-validated`, `launch-validated`
   - Flag unknown evidence types (note: `_meta` blocks in the field carry structural markers like `schema` / `assessment` / `not-yet-populated` — flag these only when they appear OUTSIDE `_meta`; inside `_meta` they describe the file, not an evidence claim)
   - Flag evidence graded `anecdotal` or better whose only sources are mocked personas / `internal_simulated` (honesty check — simulated evidence sits at `speculation` on the ladder regardless of how vivid it reads)
   - Every `source_class:` value must be one of the values in the SHIPPED SCHEMA
     enum — read `${CLAUDE_PLUGIN_ROOT}/schemas/canvas/_common.schema.json#$defs/source_class`
     and compare against that, exactly as the `evidence_type` rule above already does.
     **Do NOT hardcode the list here.** Until v0.90.0 this step named five values while
     the schema had six; `pointer` is valid, `check_source_independence.py` handles it
     correctly, and a dogfood canvas used it 61 times. Following the prose produced 61
     phantom violations — the documented-rule-diverges-from-enforcement class, in a step
     whose own sibling rule says to read the schema.
   - Flag `internal_stakeholder` evidence with confidence > 0.5 that has `validated: false` or no `validated` field — stakeholder beliefs should not carry high confidence without external validation (Brown: organizational mythology)
   - Flag L2 opportunity canvas entries where ALL evidence is `internal_stakeholder` or `internal_desk` — no external human voice heard (Spool: secondhand research insufficient)

6. **Check for orphaned references**:
   - Canvas files that reference other canvas files (e.g., jobs-to-be-done.yml referencing opportunities.yml) -- verify the referenced file exists
   - Diamond references to canvas files -- verify they exist

7. **Check evidence freshness** (evidence decay):
   - Scan all `provenance` blocks across canvas files for `validated_at` or `captured_at` timestamps
   - Compare against staleness thresholds from `${CLAUDE_PLUGIN_ROOT}/engine/evidence-decay.md`:
     - User needs/interviews: 90 days
     - Competitive intelligence: 90 days
     - Strategic assumptions: 180 days
     - Technical feasibility: 120 days
     - DORA/delivery metrics: 30 days
   - Flag evidence past threshold as warning; past 3x threshold as critical
   - Suggest refresh actions: "Evidence in [file] is [N] days old. Run `/mycelium:user-interview` or `/mycelium:log-evidence` to refresh."
   - Note: corrections and patterns do NOT decay — process learnings are timeless

7a. **Check that citations still resolve** (link rot, v0.205.0). Age is one axis of decay; a citation that 404s is the other, and until 0.205.0 nothing here asked. Run:
   ```bash
   python3 "${CLAUDE_PLUGIN_ROOT}/scripts/check_evidence_links.py" --project-dir .
   ```
   It probes every http(s) URL cited under `.claude/canvas`, `diamonds`, `harness`, `memory`, `evals` and `docs/`, and writes a dated snapshot to `.claude/evals/metrics/evidence-links/`. It self-throttles to once per 14 days (`--force` to run anyway), so on most runs it prints "skipped" and the previous snapshot stands. Read the buckets, not the total:
   - **ROTTED** (failed on two consecutive runs) → a warning naming the claim that cites it. Before deleting anything: the four found on 2026-08-17 had all MOVED, two under a different title. Search for the title before the URL.
   - **pending** (first failing run) → info only; a single 404 can be a deploy blip. It is confirmed or cleared on the next run, never by a same-day re-run.
   - **blocked** (401/403) → NOT rot; a human can open these. Those marked `needs_browser_check` are an ASK: open them in the browser and record the verdict with `--mark-verified <url> --verdict ok|gone|unclear`, so the check stops asking.
   - **unknown** (429, 5xx, timeout, DNS/TLS) → not a finding in either direction; a large count means the run was throttled, not the evidence base rotting.
   The framework's own citations are not the consumer's to check and are never scanned (a dead link in a skill doc is one upstream defect, not N project findings).

7b. **Check metric snapshot freshness** (v0.14):
   - If `.claude/jit-tooling/active-metrics.yml` exists, for each `status: active` source:
     - Find the newest snapshot in `.claude/evals/metrics/<source>/`.
     - If >7 days old: warning ("[source] snapshot is [N] days old — run `/mycelium:metrics-pull` to refresh").
     - If >30 days old: critical (evidence this stale is worse than no metric reference — anchors old state).
     - If missing entirely: info-level ("No snapshots yet for [source]. Run `/mycelium:metrics-pull`.").
   - Also check per-adapter freshness: for each adapter file in `${CLAUDE_PLUGIN_ROOT}/jit-tooling/metrics-adapters/`, if `last_known_working` is >180 days old, flag as warning suggesting regeneration via `metrics-adapters/GENERATING.md`.
   - Source: v0.14 metrics harvesting. Metric evidence has a faster staleness curve than interview evidence because the underlying data changes continuously.

8. **Check cross-reference integrity** (leaf lifecycle):
   - Every GIST idea with `source_leaf_id` → verify (a) the leaf exists in `opportunities.yml` and is not in `archived-solutions.yml` without the GIST being shelved, AND (b) the leaf's #1 riskiest assumption carries a recorded test **verdict of `validated`** (v0.54.0 — Torres selection: a GIST idea may only trace to a leaf that PASSED its assumption test, not one that merely exists or scored high on ICE). Flag a GIST idea whose source leaf has an untested / `partial` / `invalidated` riskiest assumption as a broken graduation (G-L2 REVIEW blocks it).
   - Every service entry with `gist_id` → verify that GIST idea exists
   - Every threat model entry with `solution_id` → verify that solution exists
   - Every go-to-market `feedback_loop` entry with `source_leaf_id` → verify leaf exists
   - Flag broken references as warnings ("Zombie Solution" anti-pattern)

7e. **Check that Cynefin classifications have not gone stale:**

```bash
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/check_cynefin_freshness.py" --project-dir .
```

   The Cynefin gate is Required at exactly ONE decision — `start_experiment` — so a domain is
   classified once per diamond and nothing re-runs it. **That matters because the domain drives
   METHOD selection**: Complicated routes to expert analysis, Complex to probe-sense-respond. A
   node classified on three interviews and never revisited after twenty more is routed by the
   wrong method, confidently, on current data.

   **Read UNCHECKABLE as a finding, not a pass.** A classification with no `cynefin_classified_at`
   cannot be compared to anything. Measured on the dogfood canvas at adoption: **75
   classifications, 0 checkable.** Baseline-gated for exactly that reason — failing all 75 would
   force backfilling dates nobody knows, and inventing a classification date is the fabrication
   this framework refuses elsewhere. Run `--write-baseline` ONCE; a classification written
   afterwards must carry its date.

   **A STALE row is a prompt to re-run `/mycelium:cynefin-classify`, never a verdict that the old
   domain was wrong.** Evidence can land and leave a classification correct. What is not
   acceptable is routing work by a classification that has never seen the data.

7d. **Check that stored ICE aggregates use the algorithm the framework documents:**

```bash
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/check_ice_aggregate.py" --project-dir .
```

   **The rule since 0.319.0: a stored aggregate is the PRODUCT of its factors.** `ice-score` and
   `docs/errata.md` A7 say ICE is Impact x Confidence x Ease, as Gilad defines it (*Evidence-Guided*,
   ch. 3: *"simply the three values multiplied together"*). From v0.238.0 to 0.318.x this step
   checked the opposite, that an aggregate was the **average** (Ellis, *Hacking Growth*: *"those
   ratings are averaged"*; errata A1), because that was the documented rule then.

   Why the check exists at all, unchanged: A1 told consumers to *"re-check decisions that turned on
   them"*, and until v0.238.0 nothing checked whether anyone did. Measured on the dogfood canvas the
   day this step was written: **14 of 14 verifiable aggregates were products, zero were averages**,
   three releases after the erratum shipped.

   **It is baseline-gated on purpose, and the baseline is not a snooze.** The aggregates that are
   not the product when the baseline is taken are recorded, each with its value, and the check fails
   only on one written or changed afterwards. An average on a shipped or discarded leaf (written
   from 0.229.0 to 0.318.x) is the honest record of how that call was actually made; re-scoring it
   now would only make a closed decision look compliant, which is the backfill
   `check_leaf_lifecycle` refuses in plain words. **The check never rewrites canvas data, and you
   must not either.**

   **Read the exit and the first word of the verdict:**
   - `OK` (exit 0): nothing that is not the product has appeared or changed since the baseline.
   - `FAIL` (exit 1): a new or changed aggregate is not the product of its factors. Fix that score
     with `/mycelium:ice-score`. **Adding a new failure to the baseline is the one use of
     `--write-baseline` that is wrong** — it records a fresh mistake as history.
   - `CANNOT ASSESS` (exit 2): aggregates that are not the product exist, and no baseline taken
     under the 0.319.0 rule says which were already there. This is what a project sees on its
     first run after upgrading, because a baseline written before 0.319.0 lists the old products
     and not the averages. It is not a failure of those scores and it is not a pass. If they were
     written before the project took 0.319.0, run `--write-baseline` ONCE (the earlier list is
     carried over in the file as a record) and commit the baseline. If any was written after, fix
     that score first.

   **Read the UNVERIFIABLE bucket, it is not a pass.** An aggregate stored without its factors
   cannot be recomputed at all; the check says so rather than counting it clean.

   **What a green does NOT mean.** It checks one arithmetic identity. Whether Impact, Confidence and
   Ease were honestly assessed is invisible from here — and a nearly-constant Ease column across a
   corpus (8 of 15 at exactly 5 on the dogfood canvas) is the usual sign that one dimension is
   carrying no information and ICE has quietly become a two-factor score.

7c. **Run the do-not-cite register scan** — do NOT re-derive this from prose:

```bash
python3 "${CLAUDE_PLUGIN_ROOT}/scripts/check_citations.py" --project-dir .
```

   Reports any canvas line repeating a claim the project has already ruled against, printing the
   register entry VERBATIM. It reads `.claude/harness/do-not-cite.yml`; with no register it says
   NOTHING WAS CHECKED rather than passing.

   **Why it is a script and not a rule in this file.** A do-not-cite register existed in one
   project's agent memory and failed twice in a single day (2026-09-01): once by not being read
   before a citation was written into two canvas files, and once by having a narrow entry
   PARAPHRASED into a broad one that was then acted on, rewriting four surfaces that were already
   correct. The rule was right both times and was not consulted at the moment of use.

   **It is not a lexical guard.** It matches a curated list a human wrote, so it cannot fire on a
   claim nobody has ruled on. That distinction matters here: the sibling `absence-claim-guard` hook
   matches a prose signature and was consumer-measured at 29 lifetime fires, 16 in one day, and
   zero of that day's four confirmed errors caught. On first run against a real 25-file canvas this
   check found 3 true positives — including two in a file that an earlier manual correction pass on
   the same claims had missed entirely.

8b. **Check scenario health** (Hoskins):
   - If `.claude/canvas/scenarios.yml` exists:
     - Every scenario must have all three Hoskins elements populated (motivation, persona, simulation) — flag incomplete scenarios (corrected 2026-07-01: the model has THREE elements; the prior "persona/means/motive/simulation" was a distortion — "Means" is not a Hoskins element)
     - Every scenario must have `lifecycle.born_at` set — flag if missing (orphan scenario with no origin)
     - Every scenario with `confidence > 0.5` must have evidence sources — flag unsupported confidence
     - Every scenario referenced in `lifecycle.designed_against[]` → verify the solution exists in `opportunities.yml` or `gist.yml`
     - Every scenario referenced in `lifecycle.tested_against[]` → verify test date is not in the future
     - Flag scenarios with `status: draft` older than 30 days (stale draft — either promote or discard)
     - **Falsifiable-success check:** every scenario with `status` other than `draft` must have `simulation.success_criteria` with at least one entry carrying `observable` + `threshold` — flag a non-draft scenario whose success is only the qualitative `simulation.success_state` (an un-falsifiable scenario is a user story, not a Hoskins scenario; it cannot be run against the eval-runner)
     - **Grounding check:** a scenario listed in any `lifecycle.designed_against[]`, OR carrying `confidence > 0.3`, must have `provenance.source_class` of `external_human` or `external_data` — flag any `internal_simulated` / `evidence_type: speculation` scenario that is driving design or confidence (envision-only scenarios stay `status: draft` until a real source grounds them; a fabricated scenario feels like research because it is a story)
   - If `.claude/canvas/scenarios.yml` does NOT exist but project_type requires it (per ${CLAUDE_PLUGIN_ROOT}/engine/canvas-guidance.yml): flag as warning

8b2. **Check the entry locks** (v0.245.0). Run
   `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/scale_locks.py" --check`. Each open diamond is reported
   as `holds`, `overridden by the user` (a well-formed line for it in `.claude/state/scale-lock-ack`) or `LOCKED`,
   with what its parent has not yet established. A LOCKED diamond is a **warning**, and the finding
   is the missing artefact, not the diamond: produce the purpose, the desired outcome, the
   opportunity's evidence or the L3's confidence it names. Diamonds opened before v0.245.0 are
   judged by the same locks; editing them is never blocked, but a LOCKED delivery diamond cannot
   carry new source files (the discovery gate reads the same chain). Report any
   `scale-lock-ack line ignored` line too: an override the user meant and the lock cannot read. The locks, their
   sources and why they are artefacts at L1-L3 and a confidence band at L4-L5: `engine/diamond-rules.md`,
   Entry locks.

8c. **Check build-mode** (Patton/Cagan — the `/define-done` build-mode gate's unconditional backstop):
   - For each diamond in `active.yml` at scale **L0–L3** (build-to-learn), lint its `definition_of_done.outcome` against an earn-verb lexicon (`deploy`, `ship`, `releas`, `production`, `go live`, `roll out`, `launch`, `all users`).
   - **Ignore a match that sits inside a NEGATION** (`not`, `NOT`, `never`, `rather than`,
     `instead of` within ~40 characters before it). Added v0.90.0: this fired on two dogfood
     diamonds whose outcomes read "**NOT** shipped-a-product-through-it" and ("Bet validated",
     **not** "shipped"). Both explicitly disclaim being earn-bars, and saying so is what tripped
     the check built to catch earn-bars. Left unfixed it fires on every well-written
     build-to-learn DoD, because disclaiming the earn-bar is the natural way to write one.
   - On a match → **WARN** (do not auto-fail — this is a keyword tripwire, not the semantic adjudication): *"Possible build-to-earn goal on a build-to-learn (L0–L3) diamond. Confirm this is a ship-to-LEARN outcome (disposable / opt-in, the learning is the done-bar) and not a premature earn-bar. If it's an earn-bar, re-run `/define-done` — production rollout is the L4 outcome."*
   - This converts the birth-only, agent-adjudicated gate into a check that fires regardless of whether the run engaged the gate prose. It routes the semantic call back to a human/agent; it never adjudicates "earn-shaped" itself (that stays with `/define-done`).

8c. **Human-task reconciliation** (added v0.31.3, closes the evidence/status/consent decoupling drift — corrections.md 2026-05-28):
   - **8c(e), added v0.182.0: every evidence-bearing source lands or is an orphan.** Run
     `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/check_evidence_landing.py" --project-dir .` It reports every
     task with inbound touches or findings, every assumption-test and report file, and every user need
     as LANDED / CLAIMED_NOT_LANDED / ORPHAN / REVIEWED, and fails only on regression against the
     baseline the project committed with `--write-baseline`. 8c(b) and 8c(d) see two thirds of the
     routing problem from the task side; this sees it from the source side, for every source class.
     A CLAIMED_NOT_LANDED row is a write that reported success and did not happen: fix it first.
   - **8c(f), added v0.183.0: an open opportunity that nothing reads.** Run
     `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/check_idle_opportunities.py" --project-dir .` It lists
     every open opportunity with no open task naming it, no leaf carrying a live assumption with a
     named test, and no `what_would_move_it`, as IDLE with its age, WARN tier. Measured the day it
     was written: 50 of 66 open nodes on the dogfood canvas, 33 with no leaf at all. **Silence is
     routing, not evidence**: four of seven discards recommended that day had to be withdrawn because
     no task had ever been pointed at the node. The remedy is a reader (a task, a test, a declared
     line), a park with a resume condition, or a merge; discard only on the record. `--strict` exits
     1 for projects that have cleared the backlog.
   - **8c(g), added v0.184.0: does anything follow an advisory.** Run
     `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/advisory_ledger.py" report --project-dir .` It prints,
     per session-start advisory, how many sessions it was seen, how often the condition cleared by the
     next session, how often it was still firing, the clear rate, and the current firing streak in
     distinct days; and which advisories are muted, since when, and under what ruling. Report the
     streaks at or past the mute threshold and the clear rate of anything that has fired more than
     five times; cite these numbers under Measurement in `/bvssh-check`, which rated that dimension
     amber three assessments running on advisories nobody counted. A muted advisory is a request for a
     ruling: `advisory_ledger.py rule --id <id> --ruling keep|fix|drop --note "..."`. The ledger is
     `.claude/state/advisory-ledger.jsonl`, append-only. N/A with no ledger is a project that has not
     opened a session on 0.184.0 yet, not a clean bill.
   - **8c(h), added v0.185.0: did the harness deliver our hooks at all.** Run
     `python3 "${CLAUDE_PLUGIN_ROOT}/scripts/check_hook_delivery.py" --project-dir . --days 30`. It
     reads the harness's own transcripts for this project (the only record of a hook being
     cancelled) and reports, per hook, how many runs succeeded and how many were cancelled on
     timeout. FAIL when the SessionStart hook was cancelled: a cancelled hook delivers NOTHING, the
     operating contract included, and every check in this skill that also runs at session start
     ran nowhere. Measured on the dogfood repo 2026-09-10: 32 of 33 session starts in a month were
     cancelled at the manifest's own 5-second timeout while every test stayed green, because tests
     run the script and not the harness. Report this line FIRST; every other finding in this pass
     is conditional on it. N/A on a runtime that keeps no transcripts.

The failure this catches: a fact about a human-task lives in 2+ places (the task `status`, the evidence file it produced, the contributor's consent registry) and only the salient one gets updated, so the canvas silently drifts from reality. Three sub-checks over `.claude/canvas/human-tasks.yml#pending_tasks`:

   - **(a) Status-vs-activity staleness**: **SKIP `status: watching` ENTIRELY** (v0.132.0) — a watch owes nothing, so "untouched 90d" is its CORRECT state and flagging it is a false positive that teaches the reader to ignore this check. Before the value existed, projects hand-exempted their watches from staleness rules in prose, which is the evidence the state is real. For each remaining task whose `status` is non-terminal (NOT `completed`/`abandoned`/`stalled`), compute the latest activity date across `updated_at`, `reopened_at`, `touch_log[].date`, and `partial_findings[].date`. (`reopened_at` MUST count as activity — a task deliberately reopened today is fresh, not stale, even when its other dates are months old; the reopen convention writes `reopened_at`, so omitting it here mis-flags every reopened task. Dogfood 2026-07-05: ht-003, reopened that day, read as 70d stale because this list omitted `reopened_at`.) **THEN CHECK `horizon` / `scoring_horizon`, EXACTLY AS (b) DOES. If it is in the FUTURE, do not
     flag** — a dated horizon IS the recorded reason the task is open and quiet, which is precisely
     what this sub-check asks the author to supply. Added v0.174.0 after the 2026-09-03 dogfood run
     flagged **11 tasks and all 11 had future horizons — a 100% false-positive rate**, against this
     skill's own standard that a check firing on most of a corpus trains its reader to skip it.
     **The repair already existed one sub-check away**: v0.90.0 wrote this exemption into (b) for the
     identical reason ("the check demanded a reason that was already written in the field beside
     it") and it was never carried across. (a) was edited again at v0.132.0 to skip `watching` and
     the horizon exemption still did not travel — one rule, two adjacent sub-checks, one repaired.
     **A PASSED horizon is the opposite case and ELEVATES the flag.** A task sitting untouched past
     its OWN stated deadline is the strongest version of this finding, not an exempt one — say so in
     the message rather than treating it like any other stale task.
     If the latest activity is >21 days ago (or there is no activity date at all) AND no future
     horizon is set, flag: "ht-XXX untouched [N]d while still `[status]`[, and [N]d past its own
     horizon of [date]] — decide: mark `stalled`, mark `abandoned`, or nudge the contact.
     **Unless the task carries a `frozen_prediction` whose horizon has passed** (v0.207.0): then say "due for scoring", offer none of the three, and point at `check_instrument_contract.py`, which lists it under PREDICTIONS IN THE CANVAS. A due prediction surfaced as a cold task is a finding pointed at the wrong action, and on 2026-09-03 the task's own `do_not` forbade the nudge this line would have offered.
     Abandonment is a non-event; nothing else will surface this." (The session-start hook flags this
     at 14d for awareness; canvas-health is the deeper 21d decision prompt.)
   - **(b) Evidence-exists-but-task-open**: **FIRST, IF `status` IS `waiting` OR `watching`, THAT IS THE RECORDED REASON THE TASK STAYS OPEN — do not flag** (v0.132.0). This sub-check used to infer "legitimately waiting" from a future `horizon` date, which is a proxy for a state the author can now simply declare; an explicit status beats a date a reader has to interpret. The horizon fallback below still applies to `pending`/`in_progress` tasks. Then, for each non-terminal task, check whether it has already produced evidence — i.e. it has a populated `partial_findings` block, OR its `canvas_refs` resolve to real evidence entries in purpose.yml/user-needs.yml dated at/after the task's activity. **FIRST, CHECK `horizon` / `scoring_horizon`. If it is in the FUTURE, do not flag** —
     a dated horizon IS the recorded reason the task stays open, which is precisely what this
     sub-check asks the author to supply. Ad...

© 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

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звёзд репо bvssh-check Скилл проверяет работу по критериям Better Value Sooner Safer Happier и CALMS. Запускайте его после завершения diamond и по ходу работы. CX Codex +1 ★ 47звёзд репо bias-check Скилл для Claude, Codex и Cursor, который прогоняет чек-лист когнитивных искажений перед исследованием или важным решением. Полезен, когда агент вот-вот зафиксирует вывод. CX Codex +1 ★ 47звёзд репо assumption-test Проектирует минимальную проверку гипотез решения. Опирается на принципы тестирования Торрес и модель AFTER. CX Codex +1 ★ 47звёзд репо adopt Скилл помогает подключить Mycelium к существующему проекту: сначала спрашивает разрешение на чтение репозитория, затем отделяет выводы из кода от вопросов для обсуждения. CX Codex +1 ★ 47звёзд репо

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

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