Skip to content
Design
Skill

/learning-from-corrections

Use when the user says they adjusted the design in Figma, mentions "fix", "correct", "learn from", "I changed", "diff", "what changed", or wants the system to incorporate manual Figma edits back into the spec. Diffs the current Figma state against the last snapshot, classifies

From plugin
bridge-ds
1565 skills1 hook1 MCP
Install
$ npx -y skills add noemuch/bridge --skill learning-from-corrections --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/learning-from-corrections

Context preview

The summary Claude sees to decide when to auto-load this skill.

Use when the user says they adjusted the design in Figma, mentions "fix", "correct", "learn from", "I changed", "diff", "what changed", or wants the system to incorporate manual Figma edits back into the spec. Diffs the current Figma state against the last snapshot, classifies

SKILL.md

learning-from-corrections.SKILL.md
name: learning-from-corrections
description: Use when the user says they adjusted the design in Figma, mentions "fix", "correct", "learn from", "I changed", "diff", "what changed", or wants the system to incorporate manual Figma edits back into the spec. Diffs the current Figma state against the last snapshot, classifies each change as a DS learning or a hardcoded flag, persists learnings, and patches the active recipe.

{{ACTIVE_RULES}}

Learning From Corrections

Overview

Closes the feedback loop from manual Figma edits back into Bridge's knowledge base. Diffs the live Figma state against the saved snapshot, classifies each correction as a **LEARNING** (DS-compliant → persisted) or a **FLAG** (hardcoded → surfaced), updates `learnings.json`, and auto-patches the active recipe when eligible.

When to Use

Invoke when the user:

  • says "I adjusted it", "I fixed it in Figma", "fix", "correct", or "learn from what I changed"
  • has an active CSpec in `specs/active/` with a snapshot

Do NOT use if:

  • there is no active CSpec — the user should `make` first (use `generating-figma-design`)
  • the user wants to start fresh — use `generating-figma-design` with a new description
  • the user wants to ship — use `shipping-and-archiving`

Procedure

**Before starting, load:**

  • `references/transport-adapter.md` (repo-root) — for Figma state re-read
  • `references/compiler-reference.md` (repo-root) — for scene graph recompile (if re-executing after fix)

Prerequisites

  • Active CSpec in `specs/active/` (abort if missing: "No active CSpec. Run: `make <description>`")
  • Snapshot file exists at `specs/active/{name}-snapshot.json` (abort if missing: "No snapshot found. The design must have been generated with `make`. Run `make` first.")
  • Figma MCP transport available (see `references/transport-adapter.md` (repo-root) Section F)

---

1. Load artifacts

  • Read the active CSpec from `specs/active/{name}.cspec.yaml`
  • Read the snapshot from `specs/active/{name}-snapshot.json`
  • Read existing learnings from `knowledge-base/learnings.json` (create empty structure if file doesn't exist)
  • Load `knowledge-base/registries/variables.json` for token resolution

2. Re-extract current Figma state

Run a node tree extraction script via Plugin API execution, using the `rootNodeId` and `fileKey` from the snapshot's `meta`.

**Console transport:**

figma_execute({
  code: "return (async function() { ... extraction script with rootNodeId ... })();"
})

**Official transport:**

use_figma({
  fileKey: "{fileKey}",
  description: "Re-extract node tree for fix diff",
  code: "... extraction script without IIFE wrapper ..."
})

The extraction script walks the node tree and captures: `id`, `name`, `type`, `layoutMode`, `itemSpacing`, `padding*`, `cornerRadius`, `fills`, `boundVariables`, `width`, `height`, `componentKey`, `children`.

3. Diff snapshot vs current state

Compare the two JSON trees in context. Claude performs this comparison directly.

**Match strategy:**

  • Match nodes by `id` (stable across edits)
  • For each matched node, compare:
  • Layout: `layoutMode`, `itemSpacing`, `paddingTop/Bottom/Left/Right`
  • Visual: `cornerRadius`, `fills`, `boundVariables`
  • Size: `width`, `height`
  • Component: `componentKey` (detect swapped components)
  • Detect **added nodes** (present in current, absent in snapshot)
  • Detect **removed nodes** (present in snapshot, absent in current)
  • Detect **property changes** (same node, different values)

**Ignore:**

  • Pure name changes (layer renaming)
  • Position changes (x, y) unless they indicate a structural move (re-parenting)

4. Classify changes

For each detected change:

Does the new value use a DS token (bound variable)?
  -> YES: Classify as LEARNING (DS-compliant correction)
  -> NO (hardcoded hex, raw px, unbound): Classify as FLAG (needs attention)

**Token resolution:** Check `boundVariables` in the current tree. If the property has a bound variable ID, resolve it against `registries/variables.json` to get the token name.

5. Save learnings

For each LEARNING-classified change:

1. **Determine context:**

  • `screenType`: from the CSpec's `meta.pattern` or `intent`
  • `component`: nearest component ancestor name, or the node's own name if it's a component instance
  • `section`: parent frame name (e.g., "header", "content", "sidebar")

2. **Check for existing learning:** Search `learnings.json` for a learning with matching `context` + `change.property` + `change.to.token`

  • If found: increment `signals`, append to `history`
  • If not found: create new learning entry

3. **Generate rule:** Write a human-readable rule describing the preference (e.g., "For settings screens, cards use spacing/medium (not large)")

4. **Check promotion:** After updating signals, check if any contextual learning qualifies for global promotion:

  • `signals >= 3`
  • Observations from >= 2 different `screenType` values
  • No contradiction (same property pointing to different tokens in different learnings)

6. Extract flags

For each FLAG-classified change:

1. Create a flag entry with the CSpec name, node description, and what was hardcoded 2. Add to `flags` array in `learnings.json` 3. Suggest the correct DS token if one exists: "Node {name} uses hardcoded {value}. Consider using {$token} instead."

7. Check recipe patch eligibility

If a recipe was used (check `snapshot.meta.recipe`):

1. Count the number of LEARNING signals from this fix cycle 2. If signals >= 2 for the same recipe context:

  • Load the recipe file
  • Patch the recipe's `graph` to reflect the learned changes
  • Increment recipe `version`, update `lastEvolvedAt`
  • Add entry to recipe `evolution_log`
  • Report: "Recipe {name} patched with {n} corrections (v{version})"

If a learning is promoted to **global** scope, scan ALL recipes and patch any where the change applies.

8. Update CSpec

If learnings were extracted (DS-compliant chan

Read more
Ships withbridge-ds

Design in Figma with Claude Code. Bridge connects your terminal to the Figma Plugin API via WebSocket.

Get the whole plugin
Stats
156
Stars
13
Forks
Maintained
Maintenance
TypeScript
Language
MIT
License
2mo ago
Last commit
5mo ago
Created

Repo: noemuch/bridge