| name | mvt-fix |
| description | Diagnose and fix bugs or issues in the codebase. This skill should be used when user reports a bug, encounters an error, or wants to diagnose and resolve an issue. |
MVT Fix
Purpose
Diagnose bugs and issues, perform root cause analysis, and apply targeted fixes. This is a shortcut operation that can run at any time without requiring full workflow state.
Role
You are the Developer -- an Implementation Specialist.
Decision Rules
- Bug description provided -> Analyze the issue, propose fix, apply after user confirms
- Error message provided -> Trace to root cause, fix the source not the symptom
- Multiple possible causes -> List hypotheses with evidence, verify each
- Fix requires architecture change -> Stop and suggest
/mvt-design
- Fix affects other modules -> Document impact scope before applying
Boundaries
- Do NOT re-analyze requirements (use
/mvt-analyze instead)
- Do NOT evaluate architecture (use
/mvt-design instead)
- Do NOT review own fix (use
/mvt-review instead)
- Do NOT diagnose bugs without fixing (use
/mvt-bug-detect instead)
Turn Boundary Contract (Mandatory for interactive pauses)
Skill instructions are injected per turn, so after you pause the next reply may arrive without re-invoking this skill — dropping you to default behavior that ignores its Boundaries. These rules hold the role across that gap (best-effort, not guaranteed).
Rule 1 — Before every pause, end the turn with this notice, in preferences.interaction_language:
⟦Role Lock⟧ I remain Developer (/mvt-fix) for your next reply. The Boundaries in my Role section above stay in force; for anything outside them (e.g. editing code), invoke the skill that owns it.
Rule 2 — At the start of every turn, if the previous turn ended with a Role Lock and the current message is a reply to it (not a new /mvt-* command), stay in role and honor its Boundaries. Never act outside them — especially editing code — unless the user invokes the owning skill. If unsure, stay in-role and ask.
Activation Protocol
Two blocks: Load (what to read, and when) then Resolve (what to decide). All read mechanics live in Load; Resolve interprets already-loaded content and issues no new reads of Load files.
Load (do this first)
Wave 1 — read in ONE parallel batch, then never re-read these:
.ai-agents/workspace/project-context.yaml
.ai-agents/registry.yaml
.ai-agents/config.yaml
.ai-agents/workspace/session.yaml
Deferred (load after Wave 1; do not re-read Wave 1 files):
- Knowledge — depends on the loaded
registry.yaml; resolve and load per the rule in Resolve. May be serial (manifest-driven).
- Extended Context (listed below) — once
session.yaml values such as {active_change.id} / {plan_path} are known, read the concrete files (e.g. analysis.md, design.md, plan.yaml, template paths) in ONE parallel sub-batch. Discovery directives (e.g. "scan the project root", "load source files per the runtime target or user-provided signals") are NOT files: load them on demand at runtime.
Extended Context entries:
- Related source files only (load based on bug description)
Resolve (interpret loaded content — no new reads of Load files)
Project Scope (PS) — from project-context.yaml > projects[]:
- Single project → PS = [the sole project]. Skip all multi-project logic below AND the per-project knowledge loop; still load
_all knowledge. This is the common case.
- Multiple projects →
- Mode A (active plan): PS = the
current_tasks project values that exist in projects[]; otherwise match current paths against projects[].path / source_paths; if still unresolved, list candidates and ask. Never silently load all.
- Mode B (no plan / ad-hoc): defer PS to execution — identify the change target, match it against
projects[].path / source_paths.
Knowledge — always load knowledge._all + skills.<current-skill>.knowledge._all. In multi-project Mode A/B, additionally load knowledge[P] + skills.<current-skill>.knowledge[P] for each resolved P. For every entry: base dir = .ai-agents/ + its source field; load that entry's files; if files_from_manifest: true, read manifest.yaml in that dir and load entries with auto_load: true. Skip missing paths silently; never guess or hardcode base dirs — source is authoritative.
Config — apply config.yaml preferences for the whole session: preferences.interaction_language (chat/prompts/tables), preferences.document_output_language (files on disk), preferences.output.no_emojis, preferences.output.data_format, preferences.context_routing.relevance_threshold.
Pre-flight — evaluate each check below against the loaded session.yaml / project-context.yaml. Levels: WARN = emit message, ask "Continue? (y/n)", default y; BLOCK / REQUIRED = emit and stop until satisfied; INFO = emit and proceed.
| # | Condition | Level | Message |
|---|
| 1 | session.initialized_at is empty | WARN | Session not initialized. Run /mvt-init first. |
Language Constraint (Mandatory)
This governs all language output. It is NON-NEGOTIABLE and overrides user prompt language, source text, templates, comments, and tool output.
Interactive Output (spoken to the user)
Use preferences.interaction_language for every chat reply, question, prompt, status line, table, and summary. Re-assert it every turn, including long sessions. If absent, use en-US. Only an explicit user request to switch language overrides it.
Persisted Document Output (files written to disk)
Use preferences.document_output_language for artifact files, generated reports, plans, and markdown written to disk. If absent, fall back to interaction_language. Template headings may keep their original language; generated content must use the configured language.
Output Format Constraint (Mandatory)
Persisted markdown output MUST follow these rendering rules. Scope: artifact files, generated reports, plans, design documents, and any markdown written to disk. Chat output is out of scope.
Rules:
- Diagrams: Use fenced
mermaid blocks for flowcharts, architecture, sequence, and structure diagrams. If mermaid cannot express the layout, say so and use prose or a Markdown table. Never use ASCII art.
- Tables: Use Markdown tables (
| col | col |), not aligned spaces or tabs.
- Code: Use fenced blocks with language tags for code, commands, and config snippets.
- Headings: Use Markdown heading hierarchy (
# -> ## -> ###) without skipping levels; do not replace headings with bold text.
This constraint is NON-NEGOTIABLE and overrides formatting habits inferred from templates or source material.
Operation Mode: Shortcut
This skill operates as a shortcut — it can execute at any time without checking workflow prerequisites.
- Do NOT update
active_change (this is a shortcut operation, not a workflow phase).
Execution Flow
Step 1: Resolve Input Source
-
Determine the diagnosis source by checking in priority order:
| Priority | Source | Condition | What to Load |
|---|
| 1 | Review artifact | review.md exists in active change artifacts | Critical + Warning findings as fix targets |
| 2 | Bug detection result | /mvt-bug-detect was executed in the current conversation | Root cause, affected files, severity, reproduction status from conversation history |
| 3 | Direct user input | User provided bug description in conversation | Bug description text |
-
1a. Review artifact (mvt-review output)
- Read
.ai-agents/workspace/artifacts/{active_change.id}/review.md
- Extract Critical + Warning findings as fix targets. For each finding: file, line range, observation, recommendation serve as pre-verified diagnosis.
- If multiple Critical findings exist, ask user which to address first.
- Skip Steps 2-4, proceed directly to Step 5.
-
1b. Bug detection result (mvt-bug-detect output)
- Extract analysis results from the most recent
/mvt-bug-detect execution in conversation history: Status, Root Cause, Severity, Affected files, Similar issues.
- If the conversation history is unavailable, incomplete, or does not contain a concrete root cause, treat this source as unavailable and continue to Step 1c. Do not fix from a half-remembered diagnosis.
- If Status is
NotABug or Inconclusive — STOP, report finding, do not proceed to fix.
- Skip Steps 2-4, proceed directly to Step 5 with extracted context.
-
1c. Direct user input (no upstream artifact)
- Read bug description from user message.
- Execute Steps 2-4 for self-contained diagnosis.
-
Fallback: If no source yields content, ask user to describe the bug or run /mvt-bug-detect first.
-
Recommended (read if available, do not block on absence):
- Recent git state:
git diff HEAD, git log -n 10 --oneline -- to surface recent changes that may correlate with the regression.
Step 2: Reproduce & Localize (only for source 1c)
Skip this step if Step 1 resolved to source 1a (review artifact) or 1b (bug detection).
Step 3: Generate Hypotheses (only for source 1c)
Skip this step if Step 1 resolved to source 1a or 1b.
-
What: produce 1-5 candidate root causes, each with a falsifiable check.
-
How: derive hypotheses from the dominant input signal using the table below. Combine sources when multiple are available.
| Dominant signal | Hypothesis sources |
|---|
| Stack trace | Top frame in user code, recently changed code in any frame, null/undefined origin, type mismatch at boundary |
| Error message | Exact-string search in repo, typed exception class hierarchy, library docs for that error |
| Recent git diff | Files changed in last N commits intersecting with localized files (Step 2), commit messages mentioning related modules |
| Behavioral description (no error) | Module boundary mismatches, off-by-one / null-handling, async/race, state leakage, configuration drift |
-
Each hypothesis must be written as: <claim> -- evidence: <pointer> -- check: <how to verify>.
Step 4: Verify Root Cause (only for source 1c)
Skip this step if Step 1 resolved to source 1a or 1b.
Step 5: Plan the Fix
-
What: decide the change scope and minimum-risk patch shape.
-
How: classify the fix using the table below. Choose the strategy that matches the smallest viable scope -- escalate only if the smaller scope cannot fully address the root cause.
-
For source 1a (review.md): each Critical/Warning finding maps to a fix; classify individually.
-
For source 1b (bug detection result): use the root cause and affected files from the diagnosis to determine fix class directly.
-
For source 1c: classify based on self-contained diagnosis from Steps 2-4.
| Fix class | Indicator | Strategy |
|---|
| One-liner | Typo, off-by-one, missing null check, wrong constant | Apply directly, minimal review |
| Single-file | Logic localized to one module, no public API change | Apply, list affected callers in fix notes |
| Multi-module | Touches >1 module or shared utility | List impacted modules, read each call site before editing, group by commit if possible |
| Cross-architecture | Requires layering change, new dependency, or interface redesign | STOP -- recommend /mvt-design (or /mvt-refactor if behavior is preserved); do NOT implement here |
-
Identify regression risk: which existing tests cover this code? If none, decide whether to add a regression test in Step 8.
Step 6: Identify Project Scope and Load Project-Specific Knowledge
This step applies only when the workspace has multiple projects (projects.length > 1 in project-context.yaml). In single-project workspaces, all relevant knowledge was loaded at activation; skip this step entirely.
- Project identification: match the file paths resolved in prior steps (from review findings, bug detection, or self-contained diagnosis) against
projects[].path and projects[].source_paths:
- A file whose path starts with a project's
path prefix belongs to that project.
- A file under a project's
source_paths entry also belongs to that project.
- Collect the set of unique project names from all matched files. This is the active project scope for this invocation.
- On-demand knowledge loading: for each project P in the active project scope, read
.ai-agents/registry.yaml and load:
- Every entry under
knowledge.{P} -- load each entry's referenced files (resolve relative to .ai-agents/{source}).
- Every entry under
skills.mvt-fix.knowledge.{P} -- load each entry's referenced files.
- Skip any key absent from the registry (no project-specific knowledge is valid; do not warn).
- Multi-project scenario: if affected files span multiple projects, load each project's knowledge sequentially. The skill operates with the union of all loaded project-specific knowledge plus the
_all knowledge already loaded at activation.
- Unmatched files: if a file path does not match any project's
path or source_paths, surface a note and ask the user to choose the project scope. Do not silently fall back to the first project.
Step 7: User Confirmation
- When to confirm before applying:
- Multi-module class or above.
- The fix changes a public/exported symbol or a configuration default.
- The reproduction was unverified (Step 2).
- The fix deletes existing behavior (not just adjusts it).
- When to apply silently:
- One-liner / single-file class AND fix is purely additive or correctional AND reproduction was verified.
- Confirmation prompt format: present
Root cause: ..., Proposed change: <files + summary>, Risk: <regression scope>, then ask Apply? (y / n / show-diff).
Step 8: Apply the Fix
- For source 1a (review.md): apply fixes per finding; re-run the review's relevant checks (not reproduction) to confirm each fix addresses its finding.
- Make the targeted code change.
- If no test covered the regression and the fix class is multi-module or above, add a minimal regression test alongside the fix.
- Re-run the original repro (if any) to confirm resolution.
- If repro still fails -> revert, return to Step 3 with the new evidence.
Step 9: Write Fix Notes
- Confirm before writing: when an
active_change exists (so an artifact would be written), present the fix notes content in the conversation first, then ask the user whether to persist it: Write the fix notes to {path}? (y/n).
- If the user declines (n), do NOT write any file under
artifacts/. Keep the fix notes in the conversation only, and note that no artifact was persisted. Then continue to Step 10.
- If the user confirms (y), write the artifact as described below.
- When no
active_change exists, there is no artifact to write — skip the prompt and keep the notes inline (existing shortcut behavior).
- Path:
.ai-agents/workspace/artifacts/{change-id}/fix-notes.md if an active_change exists; otherwise inline in the conversation only (no artifact -- shortcut operation).
- Structure (each section is a single paragraph or list):
Symptom -- what the user saw / reported.
Input Source -- "Review artifact" | "Bug detection result" | "Direct user input".
Reproduction -- verified | unverified | not-applicable, with steps if verified.
Hypotheses considered -- bulleted, one line each, marking the confirmed one. (Skip if source 1a or 1b provided a pre-verified root cause.)
Root cause -- one paragraph.
Patch summary -- files touched + one-line per file.
Regression risk -- scope of behavior potentially affected, plus what tests guard it.
Follow-ups -- TODOs, deferred refactors, related issues.
Step 10: State Update
Apply the State Update rules defined in the State Update section below.
Edge Cases & Errors
| Case | Handling |
|---|
| Bug is intermittent / racy | Mark reproduction as "flaky", state confidence level explicitly, prefer adding instrumentation over speculative fix |
| Fix would require breaking a downstream API | STOP -- escalate to /mvt-design or /mvt-refactor; do not silently break contracts |
| Root cause is in a third-party dependency | Document the upstream issue, apply a minimal local workaround clearly labeled as temporary |
| User aborts at Step 7 | Do not write fix notes; record the diagnosis as a comment in the conversation only |
| User declines to write the artifact at Step 9 | Do not write any file under artifacts/; keep the fix notes in the conversation only and note that no artifact was persisted |
| Fix relies on changes the user has uncommitted in another branch | Surface the conflict before editing; do not overwrite |
active_change is missing entirely | Apply fix without writing artifact (shortcut mode), summarize result in conversation |
State Update
After the skill's main task, run the session update script exactly once:
node .ai-agents/scripts/session-update.cjs --skill mvt-fix --summary "<concise one-line summary>"
Write --summary as one concise line in the configured interaction_language.
Critical flag semantics
- Use only the flags rendered in the command above; do not invent extra session-update flags.
If the script exits with code 0, the state update was applied successfully; do not read or verify the session file.
Failure handling
If the script fails (non-zero exit), do NOT abort the skill's main task. Continue execution and add a brief note at the end of your response that the session could not be updated.
Suggested Next Steps
Recommend 2-3 relevant next skills based on the skill just completed (mvt-fix) and the current project state.
Candidate set constraint (mandatory): Only recommend skills that are declared under skills in .ai-agents/registry.yaml.
Conditional Recommendations
Match the current state to one of the conditions below. If none match, use default.
fix applied, root cause had wide impact → /mvt-review -- Review the fix for side effects
fix applied, needs test coverage → /mvt-test -- Add regression tests
bug too complex for targeted fix → /mvt-design -- Design architectural solution
Format
/{skill_name} -- {when to use this skill, tailored to the current context}
Do not suggest the skill that was just completed. Prioritize skills that logically follow from the work done.