| name | wp-changes |
| description | Query the AI Change Ledger on a connected target — the writes the MCP recorded through the companion (RestTarget only), categorized; toggle on/off; panic-revert recent changes. Phase = Recovery. |
| when_to_use | site broke after AI activity ("ตอบ tool หลังเปิด AI แล้วเว็บพัง"), OR user wants to audit "อะไรที่ AI แก้ไปบ้างวันนี้", OR debug a regression by bisecting AI changes, OR roll back a single AI write without affecting others |
| tier | 1 |
| phase | recovery |
| mode | {"standalone":{"role":"change audit + report","output":"full diff report with risk annotations"},"with-rolepod":{"role":"WP diff summary provider","caller":"rolepod:review-code","output":"diff summary only (files touched, risk level) + manifest.json"}} |
Mode selection
If the marker file $GIT_ROOT/.rolepod/parent-active exists, follow the
with-rolepod mode declared in the frontmatter — the underlying
rolepod_wp_changes_query MCP tool automatically writes a diff.json +
manifest.json to
<git-root>/.rolepod/evidence/<ts>-rolepod-wplab-wp-changes/ (protocol
rolepod/v1, phase review) so the parent's review-code orchestrator can
consume it.
Otherwise, follow standalone mode — print the full diff report with risk
annotations and remediation suggestions.
GIT_ROOT=$(git rev-parse --show-toplevel 2>/dev/null) || GIT_ROOT="$PWD"
if [ -f "$GIT_ROOT/.rolepod/parent-active" ]; then
MODE=with-rolepod
else
MODE=standalone
fi
The MCP tool handles evidence emission internally via
src/lib/rolepodEvidence.ts; skill bodies do not need to write the manifest
themselves.
WP Changes
The rollback skill. Writes the MCP issues through the companion (v2.3+) are recorded in the Change Ledger (categorized, before+after state, applied flag). Coverage is NOT total: the ledger records on RestTarget connections only, and a row's reversible flag says whether the companion can actually undo it — a menu, a nav-menu item, or an Elementor _elementor_data write is recorded reversible:false with a manual-undo note. Writes on a local/ssh/docker target are not recorded at all; changes_query returns ledger_available:false there. This skill queries the ledger, toggles individual rows, runs git-bisect-style binary narrowing, and panic-disables reversible changes in a time window when the site is on fire.
Iron Rule
1. NEVER panic-revert without first running `wp-health-check` to confirm the site is actually broken — panic disables real production changes; using it as a "I'm curious" tool causes user-visible regressions.
2. NEVER toggle a row with `reversible: 0` and expect the side effect to undo — execute_php side effects and wp-cli destructive ops are flagged irreversible at record time; the toggle flips the flag but cannot replay the inverse. Surface this verbatim.
3. ALWAYS surface `target_descriptor` + `source_tool` when listing changes — user needs to recognize what each row IS, not just an opaque ID.
When to use
- "เว็บพังหลัง AI แก้ของ" — panic + bisect flow.
- "What did AI do in the last hour?" — query with
since_minutes: 60.
- "Undo only the last theme.json change, keep the rest" — single toggle.
- "Re-enable the changes I disabled earlier" — bulk toggle.
- Pre-migration: query ledger to know what changed before you snapshot.
Skip when:
- The site is up + user has no complaint → no need to touch ledger.
- Plain "is it up" →
wp-health-check.
- Multi-probe diagnosis →
wp-diagnose.
Boundary
Owns:
rolepod_wp_changes_query — filter the ledger.
rolepod_wp_changes_toggle — single on/off.
rolepod_wp_changes_toggle_bulk — batch on/off (used for bisect).
rolepod_wp_changes_panic — disable all in window.
- The bisect workflow (re-enable batches, narrow down the bad row).
Does not own:
- Recording changes — that is automatic in writer tools (wp-content, wp-edit-*, wp-scaffold).
- Health/diagnostic probe →
wp-health-check / wp-diagnose.
- Per-category revert semantics — those live in companion
Toggler.php.
Return / hand off:
- After panic + recovery →
wp-diagnose to understand WHY the change broke things, before re-enabling anything.
- User wants to permanently delete changes (not just toggle off) → admin UI → "Delete row" (not yet a MCP tool; defer to v1.7).
Inputs to gather
- target_id (always).
- For query: filters (
category, applied, since_minutes, source_session, limit).
- For toggle:
id + new applied boolean.
- For bulk toggle:
ids array + applied.
- For panic:
since_minutes (1-1440).
Workflow
1. Establish baseline
If the user reports "site broke", first: wp-health-check. If green, the site isn't broken — re-confirm with user before doing anything destructive.
2. Find the candidate changes
rolepod_wp_changes_query {
target_id,
applied: true,
since_minutes: <last known good minutes ago>,
limit: 50
}
The result is the list of changes that could have caused the breakage.
3. Triage
If 1-3 changes since last green → toggle off individually, verify after each.
If >3 changes → use panic + bisect:
rolepod_wp_changes_panic { target_id, since_minutes: 30 }
→ returns disabled_ids: [N..M]
wp-health-check → green (recovered).
Then bisect: re-enable half, check health.
rolepod_wp_changes_toggle_bulk { ids: [first half of disabled_ids], applied: true }
wp-health-check → if red, bad row is in first half; else in second half.
Narrow to single bad row. Leave it disabled. Surface to user.
4. Surface
For every toggle action, surface: id + category/subcategory + side-effect detail + new applied state. The user must SEE what the system did.
If a matching Rolepod agent is available
rolepod:debug-issue for the broader debug context this rollback fits into.
rolepod:devops-sre for prod-recovery flows.
If no matching agent is available
- Baseline (wp-health-check).
- Query candidates (since_minutes).
- If few → toggle individually with verify after each.
- If many → panic + bisect.
- Leave bad row(s) disabled, surface to user, hand off to wp-diagnose.
Output
No durable artifact in MCP. The companion's ledger row persists with toggled_at timestamp; the admin UI surfaces every toggle as a notice.
Examples
Read EVERY time the user reports a broken site after AI activity — the bisect pattern is the heart of the recovery workflow:
examples/changes-examples.md — good vs bad panic flow; good vs bad bisect narrowing.
References
Inline only. The ledger schema + per-category toggle semantics live in companion src/Audit/{ChangeLedger,ChangeRecorder,Toggler}.php.
Hard stops
wp-health-check returns green AND user says "site broke" → STOP, do not toggle anything; ask user what they actually see broken.
- A toggle returns
side_effect.ok: false AND reversible: 0 → STOP, surface the limitation; do not retry.
- Bisect lands on >1 candidate as "bad" → STOP, both rows interact; surface to user, do not auto-toggle further.
Full Rolepod enhancement
Full Rolepod adds session correlation — every AI session gets a source_session id, so changes_query { source_session: '<sess>' } retrieves exactly the work from one chat. Standalone, the user filters by since_minutes.
Next phase
- After recovery →
wp-diagnose to find WHY the bad change broke things.
- After bisect identifies the bad row → fix it (re-edit via the right edit skill, then re-enable a cleaner version).
- After permanent revert decisions → admin UI to delete rows (manual, no MCP tool yet).