/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
$ npx -y skills add noemuch/bridge --skill learning-from-corrections --agent claude-codeHow 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.mdname: 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
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
Design in Figma with Claude Code. Bridge connects your terminal to the Figma Plugin API via WebSocket.
Repo: noemuch/bridge
Other skills on bridge-ds.
- /extracting-design-system
Use when the user says "setup", "setup bridge", "extract", "extract DS", "onboard", "build knowledge base", "initialize bridge", or is starting Bridge in a project for the first time. Handles the complete bootstrap: pre-flight checks, scaffolding (docs.config.yaml, cron
Open skill - /generating-figma-design
Use when the user requests to design, create, build, generate, or make a new Figma component or screen — including phrases like "make a button", "design a settings page", "build a new card", "generate X". Produces a CSpec, compiles it to a scene graph, executes it in Figma via
Open skill - /shipping-and-archiving
Use when the user says "done", "ship it", "finish", "complete", "archive", or otherwise indicates the current design is ready to be shipped. Runs final verification (Gate B), archives the CSpec, updates history, extracts a recipe when eligible, and cleans up temp files.
Open skill - /using-bridge
Use when any Bridge command is invoked (make, fix, done, setup, drop, status) or any Figma / design-system / compiler / Bridge workflow topic is raised. Sets command priorities and iron laws (compiler-only, semantic tokens only, verification-before-ship).
Open skill

