Log Evidence Skill
The re-entry point after offline human work. Takes raw conversation notes, observations, or survey results and integrates them into the canvas with proper provenance.
Preflight: Read target canvas file(s) before any Write/Edit
Hard rule. Before issuing Write or Edit against any .claude/canvas/*.yml, use the Read tool on that file in this session. Claude Code's Read-before-Write check requires the Read tool specifically — cat/head/grep via Bash do NOT satisfy it.
Edit vs Write — different cost profiles (verified 2026-05-14):
Edit(exact-string replacement):Readwithlimit: 1satisfies the check at ~50 tokens. State-tracking is per-file, not per-byte — subsequentEditcalls work anywhere in the file. Use this for partial updates against large canvas files (e.g.,purpose.ymlat 800+ lines).Write(full replacement): do a full Read first. Write obliterates the file; you should see what you're about to replace. Thelimit:1shortcut is not appropriate here.
ID-bearing entries — scan the ID space before assigning (added 2026-05-15, v0.23.19): When adding a new component, opportunity, solution, or any other ID-bearing entry to a canvas file, run a Bash grep first to confirm the next ID in your prefix sequence is actually free:
grep "^ - id: <prefix>-" .claude/canvas/<file>.yml | sort -u
Replace <prefix> with the canvas's ID prefix (comp for landscape, opp for opportunities, sol for solutions, ht for human-tasks, etc.). Then pick the next free integer. validate_canvas.py has a duplicate-ID check (lines 230-239) that catches the failure on CI, but a duplicate can persist in the working tree for days if CI isn't run between edit and discovery — see roadmap-repo corrections.md 2026-05-15 "Duplicate canvas ID created in landscape.yml" for the worked example.
Original failure mode: anti-pattern #7 instance #5, 2026-05-09 — agent conflated Bash head with the Read tool, lost ~14k tokens to a Write-fail → remedial-full-Read → re-Write loop. The limit:1 discipline (graduated 2026-05-14, v0.23.18) prevents the second-order cost where the agent correctly follows the rule but full-Reads every time. The ID-scan discipline (graduated 2026-05-15, v0.23.19) prevents the related class where the agent reads enough of the file to satisfy the Edit check but not enough to see existing ID assignments — kin to anti-pattern #8 (Stale State Read).
If this skill writes to multiple canvas files, register each one first (limit:1 for Edit-only paths; full Read for Write paths) AND ID-scan any prefix you intend to assign.
See CLAUDE.md Canvas writes — Read before Write for the canonical rule.
When to Use
- After completing a human task from
.claude/canvas/human-tasks.yml - When the user returns from an offline conversation and has findings to record
- When SessionStart reminds about pending human tasks and the user has completed them
- When the user pastes conversation notes or interview summaries
Workflow
-
Check pending tasks:
- Read
.claude/canvas/human-tasks.ymlforpending_tasks - List them: "You have [N] pending human task(s): [objective summaries]"
- Ask: "Which task did you complete? Or paste your notes and I'll match them."
- Read
-
Guided evidence capture (if user doesn't have a filled template):
- Who did you talk to? (role and context, not name -- privacy)
- What did you learn? (open-ended first, let them tell the story)
- Any direct quotes worth capturing?
- Anything surprising or contradicting our current assumptions?
- JTBD signals: functional job, emotional job, social job?
- Any follow-up conversations needed?
-
Classify the evidence on Gilad's ladder:
- Single conversation ->
anecdotal(0.3) - 2 conversations with consistent signals ->
anecdotal(0.3), note convergence - 3+ triangulated conversations ->
data-supported(0.5-0.6) - Explain the classification: "One conversation is anecdotal evidence. We'd need 2-3 more to call it data-supported."
- Single conversation ->
-
Update canvas provenance:
- Identify the relevant canvas file and section (from the task's
canvas_refs) - Close the learning-target loop (per
engine/canvas-guidance.yml#learning_target_coupling): if any answered question carried a[target → <file>#<anchor>]tag, route the captured evidence to that exact entry, then prompt whether the open gap can now move — ON HOLD → OPEN, RE-GATED → met, or a confidence bump. Logging the evidence and retiring the gap are separate steps; the tag makes the second one explicit. If the awaited answer did NOT arrive, say so — the absence is itself a finding (the gap stays open with a note). - If the canvas entry has NO provenance object yet (early project), create one:
provenance: evidence_type: anecdotal # single conversation evidence_sources: - "interview-YYYY-MM-DD-[role-descriptor]" source_classes: - external_human captured_at: "YYYY-MM-DDTHH:MM:SSZ" confidence: 0.3 - If provenance already exists: add to
evidence_sourcesandsource_classesarrays - Update
evidence_typeif the new evidence strengthens it - Update
confidencescore with explicit reasoning - Update
captured_attimestamp
- Identify the relevant canvas file and section (from the task's
-
Close the source task — coupled to the evidence-write, not a separate afterthought (
.claude/canvas/human-tasks.yml):Writing evidence and closing the task that produced it are one action, not two. The drift
/canvas-healthsub-check8c(b)catches — "evidence exists but the task is still open" — forms precisely when step 4 lands and this step is skipped. Do not report the evidence as logged until this is done.- Default (evidence answers the task): move the task from
pending_taskstocompleted_tasks. Record:completed_at,evidence_logged_to(the canvas file#anchor from step 4),key_findings,source_class: external_human. - Partial (some signal, task not fully answered): keep the task in
pending_tasksbut append to itspartial_findings[](withdate+evidence_logged_to) AND state out loud why it stays open and what's still missing — otherwise8c(b)will flag it next health pass. An un-narrated open task with evidence attached is the drift, not the fix. - Registry sync (prevents
8c(c)drift): if this evidence came from a named contributor whose consent or attribution state changed as a result of the conversation (e.g. they granted naming permission), update the canonical attribution registry ($MYCELIUM_ATTRIBUTION_REGISTRYor the private companion repo's.claude/memory/attribution-registry.yml) in the same pass — the registry is canonical (Check 33 reads it). If the registry isn't accessible in this context, say so and leave a note rather than recording consent only in auto-memory (the mismatch8c(c)exists to catch). Never print ageneric_only/ project-name carve-out value into output.
- Default (evidence answers the task): move the task from
Task Cancellation
If the user reports a task couldn't be completed (contact unavailable, timing didn't work, etc.):
-
Ask: "Should we cancel this task or reschedule it?"
-
If cancel: move to
completed_taskswithsource_class: cancelledand a note explaining why -
If reschedule: update the task's
objectiveortarget_personaif needed, keep inpending_tasks -
Either way: "The evidence gap still exists. Consider
/mycelium:handoffto plan an alternative approach." -
Check for contradictions:
- Compare findings against existing canvas data
- If findings contradict assumptions: flag clearly
- "This contradicts [canvas section / assumption]. The user said [X] but we assumed [Y]."
- Suggest: "Consider running
/mycelium:devils-advocateto stress-test this assumption, or update the canvas with/mycelium:canvas-update."
- If findings support assumptions: note the confirmation
- "This supports [ca