一键导入
canvas-health
Lint canvas files for staleness, missing fields, inconsistent evidence types, and orphaned references. Run periodically or before major transitions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Lint canvas files for staleness, missing fields, inconsistent evidence types, and orphaned references. Run periodically or before major transitions.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Use to evaluate the current state of a diamond. Checks theory gates, confidence levels, and recommends next action.
Use when building anything USER-FACING (or with persuasion/retention/cancellation/consent/pricing flows, or that touches vulnerable people) to surface design-level harm the security/privacy/compliance gates miss: dark/deceptive patterns and foreseeable misuse. Assumes the product works as designed and asks who it could harm and whether it is Happier-negative. NUDGE, not a block.
Accessibility audit against WCAG 2.1 AA. Checks semantic HTML, ARIA, keyboard navigation, color contrast, screen reader compatibility.
Design the smallest viable test to validate or invalidate a critical assumption. Based on Torres's assumption testing framework, organized by Gilad's AFTER model (Assessment → Fact-Finding → Tests → Experiments → Release Results).
Use before any research activity or significant decision. Reviews cognitive biases relevant to the current stage.
Use to evaluate whether current work aligns with Better Value Sooner Safer Happier. Run at diamond completion and periodically.
| 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."} |
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").
/mycelium:diamond-assess)Load project configuration:
.claude/diamonds/active.yml for product_type and project_type${CLAUDE_PLUGIN_ROOT}/engine/canvas-guidance.yml for required/recommended/optional files per project typeCheck file presence:
N/M required files present, K recommended files missingCheck _meta blocks:
_meta: block_meta blockslast_validated older than 30 days (staleness warning)version field missing or at 0Check confidence consistency:
confidence: values across canvas filesevidence_type: speculation or evidence_type: assumption.claude/diamonds/active.yml confidenceCheck evidence type consistency:
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_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)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)source_class: value should be one of: external_human, external_data, internal_stakeholder, internal_desk, internal_simulated — flag unknown valuesinternal_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)internal_stakeholder or internal_desk — no external human voice heard (Spool: secondhand research insufficient)Check for orphaned references:
Check evidence freshness (evidence decay):
provenance blocks across canvas files for validated_at or captured_at timestamps${CLAUDE_PLUGIN_ROOT}/engine/evidence-decay.md:
/mycelium:user-interview or /mycelium:log-evidence to refresh."7b. Check metric snapshot freshness (v0.14):
.claude/jit-tooling/active-metrics.yml exists, for each status: active source:
.claude/evals/metrics/<source>/./mycelium:metrics-pull to refresh")./mycelium:metrics-pull.").${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_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).gist_id → verify that GIST idea existssolution_id → verify that solution existsfeedback_loop entry with source_leaf_id → verify leaf exists8b. Check scenario health (Hoskins):
.claude/canvas/scenarios.yml exists:
lifecycle.born_at set — flag if missing (orphan scenario with no origin)confidence > 0.5 must have evidence sources — flag unsupported confidencelifecycle.designed_against[] → verify the solution exists in opportunities.yml or gist.ymllifecycle.tested_against[] → verify test date is not in the futurestatus: draft older than 30 days (stale draft — either promote or discard)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)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).claude/canvas/scenarios.yml does NOT exist but project_type requires it (per ${CLAUDE_PLUGIN_ROOT}/engine/canvas-guidance.yml): flag as warning8c. Check build-mode (Patton/Cagan — the /define-done build-mode gate's unconditional backstop):
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)./define-done — production rollout is the L4 outcome."/define-done).8c. Human-task reconciliation (added v0.31.3, closes the evidence/status/consent decoupling drift — corrections.md 2026-05-28):
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: for each 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.) If the latest is >21 days ago (or no activity date at all), flag: "ht-XXX untouched [N]d while still [status] — decide: mark stalled, mark abandoned, or nudge the contact. 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: 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. If evidence exists but the task is still open, flag: "ht-XXX has captured evidence (partial_findings / linked purpose.yml entry) but status is [status] — close it (completed) or record why it stays open. Logging evidence and closing the source task are separate steps; this catches the gap." Recommend /mycelium:log-evidence should be closing the task going forward.
(c) Consent-registry sync (best-effort; cross-source): if an attribution registry is available ($MYCELIUM_ATTRIBUTION_REGISTRY or a private companion repo's .claude/memory/attribution-registry.yml), compare each contributor's consent value there against any consent state recorded in the agent's auto-memory (~/.claude/projects/<id>/memory/). Flag mismatches: "Consent for [name] is [X] in the registry but [Y] in auto-memory — the registry is canonical (Check 33 reads it); sync them." If neither source is accessible in the current context, skip this sub-check and note it was skipped. Do NOT print the literal value of any generic_only/project-name carve-out term into the report.
(d) Untracked-channel evidence (added v0.39.10, symmetric inverse of (b) — closes the drift where outreach produces evidence with no source-task at all): scan recent evidence entries across .claude/canvas/*.yml (windowed to entries dated within the last 30 days) for items with source_class: external_human whose provenance.relationship OR provenance.evidence_sources[] names an external contributor by name or handle. For each, check whether ANY human-tasks.yml entry (pending OR completed) lists that name in target_persona, touch_log, or a backfill_note. If no match, flag: "purpose.yml#L[NN] (or other canvas) records external_human evidence from [name] dated [date], but human-tasks.yml has no task covering this contributor. Backfill an ht-XXX with a backfill_note so the channel is addressable for follow-ups, learning-target coupling, and consent tracking. /mycelium:log-evidence v0.39.10+ catches this at log-time; older entries may need retroactive backfill." Skip names already flagged as registry-private (generic_only). NUDGE-tier, not gating.
Output all (a)–(d) as warnings (not critical) — they are drift, not breakage. Each names the specific ht-ID (or missing-ht contributor) and the specific action.
8d. Learning-target coupling on feedback tasks (added v0.31.6, closes the "we asked for feedback but didn't ask what we needed to learn" gap — see engine/canvas-guidance.yml#learning_target_coupling):
The failure this catches: the canvas carries open learning needs (ON HOLD / RE-GATED action flags, in-progress human-tasks naming a MISSING SIGNAL, low-confidence entries with an un-validated assumption), AND a feedback-gathering task is open, but the task's questions target none of those gaps — so the feedback returns whatever the respondent volunteers rather than the answers the canvas is waiting on. Feedback capacity is scarce and non-repeating; an un-targeted session spends it without retiring any gap.
.yml files for (i) ON HOLD / RE-GATED markers, (ii) human-tasks.yml tasks with status: in_progress whose success_criteria name a MISSING SIGNAL or un-met track, (iii) entries with confidence < 0.5 carrying a named un-validated assumption. If the open-gap set is empty, skip this check (nothing to couple to).human-tasks.yml tasks with a key_questions block, status non-terminal): check whether any question carries a [<gap-handle> → <file>#<anchor>] tag (the coupling tag) OR plainly references one of the open gaps by name. Tag format: the <gap-handle> is a short descriptive name for the open gap (e.g., [L0 adoption / cautious-learner → purpose.yml L797 + ht-002 track(c)], [anti-state #1 vocabulary wall → purpose.yml#anti_states lost-in-vocabulary]); the literal placeholder target is also accepted ([target → <file>#<anchor>]) but the descriptive form is the validated-in-use convention and is more informative at read-time. Both forms match the same \[[^\]]+→[^\]]+\] regex shape. If NONE do, flag (NUDGE): "ht-XXX gathers feedback but none of its key_questions target an open canvas gap ([list 2-3 open gaps]). Seed ≥1 learning-target question per learning_target_coupling, or record why this is pure discovery."[<gap-handle> → ref] tag whose <file>#<anchor> does not resolve to a real canvas entry (broken coupling — the gap it claimed to feed was renamed or closed): "ht-XXX question tags [ref] but that entry no longer exists — re-point or drop the tag."objective: field clearly signals non-extraction intent; if in doubt, flag with the carve-out language ("ht-XXX appears to be a [shape] task rather than feedback-extraction — apply 8d only if extraction was the intent").8e. Diamond Definition-of-Done presence (added with /mycelium:define-done — retrofit detector):
The failure this catches: a diamond reaches Deliver (or sits in any phase) with no explicit outcome bar, so "done" defaults implicitly to the harshest, least-controllable outcome — wrong for validating purpose and a demotivation engine (see docs/design/definition-of-done.md).
.claude/diamonds/active.yml. For each diamond in active_diamonds whose state is not terminal (NOT archived/killed), check for a definition_of_done block with non-empty outcome and signal./mycelium:define-done to pin what behaviour-change marks it done. The Deliver→Complete gate will block without it." Do NOT auto-fill — the question is what produces a real bar, not the field.parent) that DO have a DoD: flag if rolls_up_to is absent — "Diamond [id] is a child but its DoD names no parent outcome it rolls up to (contribution-not-summation)."9b. Check docs/ health (added 2026-05-08 with the docs restructure):
docs/ (excluding docs/receipts/cases/ which carry frontmatter) must have Audience, Time to read, and Last updated lines in the first 5 lines. Flag missing markers.is forthcoming are Phase 2 stubs. Flag any stub with Last updated older than 60 days — Phase 2 may have stalled.docs/README.md and docs/contributing/style.md:
docs/<page>.md ≤ 400 lines (hard cap; soft cap 250)docs/receipts/cases/<case>.md ≤ 250 lines (hard cap; soft cap 150)docs/changelog.md (the full version history is the artifact's purpose; pages-as-shape is a category error) and any file whose first 5 lines declare itself a log surface (e.g., **Format**: append-only log, or a similar self-declaration). The exemption is intentional and bounded — narrative docs that drift into log-shape are still flagged.docs/ file with Last updated older than 180 days gets flagged for refresh.Last updated date AND that date is approaching the 180d threshold (within 30 days of expiry, i.e., older than 150 days), surface as a cohort-validation event overdue rather than flagging each file individually. The pattern (multiple docs frozen at the same date) signals "one batch validated at that time, no individual re-touches since" — the right remediation is a single batch re-validation pass that touches each, not 13 separate touch-passes. Cohort signal is INFORMATIONAL (not FAIL/WARN); intent is to make the batch nature visible so the response matches the cause.docs/contributing/style.md.docs/receipts/cases/ must have YAML frontmatter with the required fields (id, date, contributor, contributor_link, project, mechanism_or_status, commits, subclass). Flag missing fields.docs/contributing/style.md#highlights-rotation. The flag is informational; rotation is a /mycelium:framework-health decision, not an automatic move..claude/canvas/services.yml has a service with an xai: block (i.e., AI-component product per /mycelium:xai-check), compare key fields in docs/ai-system-card.md (or equivalent system card path) against the canvas. Fields to compare: §9 "Last full audit" date vs xai.last_assessed_at; §5/§9 eval status references vs xai.fidelity block (especially when an eval has closed — samples_audited and verdict change but card prose lingers); §1 AI Act risk tier text vs xai.tier + xai.tier_provisional. NUDGE-tier flag (informational, not failing) on any mismatch >7 days old, with canvas treated as canonical and remediation pointing to a system-card edit OR an extension to sync_derived.py if the field is mechanically derivable. Worked failure 2026-06-05: docs/ai-system-card.md §5/§9 still cited 2026-05-04-xai-inline-attribution (1/10 sessions) 24 days after the eval closed 2026-05-12 at session 11 INSTRUMENT FAILED; the 2026-06-04 canvas-health spot-check missed it because no rule existed to compare card content to services.yml. This sub-check closes the gap.9c. Check action-flag timeout handling (added 2026-05-23 v0.23.43, closes a documented-rule-diverges-from-enforcement instance):
Per ${CLAUDE_PLUGIN_ROOT}/engine/canvas-guidance.yml#action_flags.transitions.timeout_handling: "ON HOLD entries with calendar conditions (e.g., 'pending May 7 evidence') that pass their named date should be flagged, not silently expired. Surface as a stale flagged item via /canvas-health (existing staleness machinery applies). Do NOT auto-transition to OPEN — the absence of the awaited evidence is itself a finding worth surfacing to the user. After 30 days past a named date with no resolution, suggest re-evaluating whether the condition is still relevant."
The convention says canvas-health surfaces this. Until v0.23.43 it didn't — the convention was written 2026-05-03 but no canvas-health check was added. This check closes that gap (cluster instance #11 of documented-rule-diverges-from-enforcement, 2026-05-23).
Concretely:
.yml files for ON HOLD markers via the keyword pattern: (ON HOLD|on hold) with a parenthetical containing a calendar date in any of: YYYY-MM-DD, Month DD, MM/DD/YYYY, or month-name forms (e.g., "May 7", "May 2026").transitions.on_hold_condition_met audit rules). Format: "Canvas [file]: item flagged ON HOLD pending [name] [date]; date passed [N] days ago. Evidence: check if [name] arrived; if yes, transition ON HOLD → OPEN per canvas-guidance#transitions; if no, leave."### Canvas Health Report entry to .claude/harness/decision-log.md/mycelium:diamond-progress) to detect health issues## Canvas Health Report
> **Status: [HEALTHY | WARNINGS | CRITICAL]** — [one-line verdict, e.g., "0 critical, 3 warnings, 1 info — system-card content stale vs services.yml; chat-UX axiom flags first-fire"]
Files checked: N canvas files, M diamonds files
### Critical Issues
- [required file missing or empty]
### Warnings
- [stale confidence, inconsistent evidence, anchored values]
### Suggestions
- [missing recommended files, absent _meta blocks]
### Coverage Summary
| Category | Required | Present | Gap |
|----------|----------|---------|-----|
| Discovery (L0-L2) | N | M | ... |
| Solution (L3) | N | M | ... |
| Delivery (L4) | N | M | ... |
| Market (L5) | N | M | ... |
Recommended actions:
- /mycelium:canvas-update [file] -- [reason]
- /mycelium:interview -- [if evidence gaps found]
- /mycelium:log-evidence -- [if confidence unsupported]
Hard rule (per CLAUDE.md Communication Rules, anti-pattern #7 write-narration-verification — mechanism Check 42, graduated v0.39.18; enforced surface expanded to this skill v0.44.0). This skill mandates multi-field canvas updates. Before narrating "updated / wrote / refreshed [canvas]" in any user-facing summary, RE-READ the value fields this skill's MANDATORY says to update and confirm they actually changed — not just _meta.last_validated or a freshness stamp. Each field you claim to have updated must reflect its new value. The symmetric half of the Read-before-Write Preflight: that one protects what gets read before a write; this one protects that the write matches the claim. Worked failures: 2026-06-05 #18 (/dora-check narrated "updated" with value fields unchanged) + #19 (/retrospective left a cycle-history aggregate un-propagated).