feat(learning): revert applied learned adjustments - #44
Open
localrivet wants to merge 1 commit into
Open
Conversation
A learned adjustment — a review-fork learned skill or a workflow tuning edit —
had no restore point once applied. Skills stored only a HASH of the prior
SKILL.md (for conflict detection), auto-mode skill writes left no row at all,
and workflow edits kept the prior binding JSON only as a conflict token. So an
applied learning was effectively baked in: the only escape was waiting for the
fork to overwrite it or deleting files by hand (the user-facing skill DELETE
endpoint doesn't even reach the learned tree).
Capture a real restore point and add a first-class revert:
- pending_writes gains prior_content (migration 0126): the FULL prior SKILL.md
or prior binding JSON, NULL for a create. Captured at every apply point —
staged skill writes, workflow tuning, and (new) an approved audit row for
AUTO-mode skill writes, which previously left no trace to undo.
- POST /agents/learnings/{id}/revert reverses an 'approved' row by writing
prior_content back through the SAME pathway that applied it (skill tool
inverse action / apply_workflow_binding). It refuses — never clobbers — when
the target no longer matches what the learning produced.
- A learned_write_reapply ctx flag distinguishes a genuine auto-mode learning
(records an audit row) from an approve/revert re-application (does not), so
approve/revert never mint duplicate learn: records.
- Inbox: applied learnings show a Revert action; a reverted/conflict chip
reflects the outcome.
Tests: pending_writes prior_content round-trip, record_applied_write lands
approved, revert only transitions applied rows.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0157ARXoiSR35pfppJT7vLeX
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
A learned adjustment — a review-fork learned skill or a workflow tuning edit — had no restore point once applied, so it was effectively baked in:
SKILL.md(for conflict detection), not the content.pending_writesrow at all — nothing to anchor an undo to.handlers/skills.rs).The only escape was waiting for the fork to overwrite it, or deleting files by hand. This is the same failure class as the memory-poisoning that started this line of work, one layer up.
Fix
Capture a real restore point and add a first-class revert.
prior_contentonpending_writes(migration0126): the FULL priorSKILL.md/ prior binding JSON,NULLfor a create. Captured at every apply point — staged skill writes (skill_tool::stage_learned_write), workflow tuning (workflow_manager), and a new approved audit row for AUTO-mode skill writes (record_applied_write/record_applied_learning), which previously left no trace.POST /api/v1/agents/learnings/{id}/revert(handlers::agents::revert_learning): reverses anapprovedrow by writingprior_contentback through the same pathway that applied it — the skill-tool inverse action (create→delete,update→update(prior),delete→create(prior)) orapply_workflow_binding. It refuses (never clobbers) when the target no longer matches what the learning produced, returningconflict.learned_write_reapplyctx flag: distinguishes a genuine auto-mode learning (records an audit row) from an approve/revert re-application (does not), so approve/revert never mint duplicatelearn:records.reverted/conflictchip reflects the outcome (routes/inbox/+page.svelte, regeneratedneboclient, i18n).Learning modes (unchanged, for context)
autoapplies directly (now with an audit row),stagedroutes to Inbox approval,offdisables learning. Revert works for anything that reached theapprovedstate underautoorstaged.Tests / verification
nebo-db:prior_contentround-trip,record_applied_writelandsapproved,revertonly transitions applied rows — 3 pass.nebo-tools: existing skill-tool suite — 7 pass, no regression.nebo-db/nebo-tools/nebo-agent/nebo-serverlibraries compile clean;pnpm checkon the app — 0 errors.libwayland-dev/protoc/BLAS + noapp/build); CI should exercise the full build.🤖 Generated with Claude Code
Generated by Claude Code