Repository navigation
feat(improve): self-healing notifications and lousho improve status - #999
Merged
Merged
Conversation
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Status reports an unjudged apply as pending with a warning, keeps going on a corrupt state.json, refuses a missing directory and prints reasons as one line of plain text; the notifier can't throw; a scheduled guard failure posts once per revision. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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.
Why
S25 of the M4 plan (
m3-notes/m4/parity.md): E8 and B4. In auto mode people learn about changes after the fact, and in manual mode they must learn that a proposal is waiting. They also need one place to see the loop's state.Changes
src/observe/alerts.ts: newAlertEventtypesimprove.pending,improve.applied,improve.rolled_back,improve.guard_failed,improve.paused,improve.canary.detailsis{ agent, dir, from, to, reason, cycle }, pluscard(the local path of a pending proposal file).src/improve/notify.ts: builds the events; the reason always goes through the audit log'splain()(no links, images, HTML or<untrusted>markers; R11). The notifier never throws: a throwing log, a throwing or rejectingalerter.postare swallowed.watch.ts,watchSteps.ts):WatchOptions.alerterandlog(default one stderr line per event). Events: a cycle that endspending,applied,guard-rolled-backorcanary-failed; a new pause (kill switch, or the self-pause after three outages); a monitor rollback or an unrolled regression, once per apply (through the harvest claim); a scheduled-guard regression, once per revision. The CLI--watchposts to thealerts.jsonwebhooks beside the observe db throughcreateAlerter.src/improve/status.tsimproveStatus(dir)andlousho improve status <dir> [--json]: mode, paused (kill switch) state, active revision, last 5 audit entries, pending proposals, the monitor's verdict (an apply it hasn't judged showspending), budget left today (cycles, automatic applies, tokens), cooldown (audited rollback or the monitor'scooldownUntil), the canary (traffic setting and the last replay verdict), the last cycle, and warnings (the monitor waiting for runs, kept unverified, an unrolled regression, an unreadablestate.json, instructions not ininstructions.md). Reasons are plain text, and the text form keeps each field on one line.docs/cli.md(status), the alerts paragraph indocs/observability.md.Testing
src/improve/watch.test.ts: an apply posts oneimprove.applied(and one stderr line); webhook and log failures never fail the cycle; a pause and a pending proposal post once each, the pending one with its local card path; a monitor rollback posts once across ticks with a rejecting webhook and a planted image link stripped from the reason;noticeEventstrips links, images, HTML and markers.src/cli/improve.test.ts:status --jsonhas every field (monitorpendingwith its warning right after an apply), the text form, a corruptstate.jsonbecomes a warning, a missing directory is refused, a planted multi-line, markdown cycle reason prints as one plain line.state.jsonare fixed in the second commit.api:update+api:check,docs:llms+docs:llms:check,docs:verify-snippets -- --skip-build,docs:ratchet(1724), vitestsrc/improve src/cli src/observe,npx fallow audit --base origin/mainafter scoped coverage.🤖 Generated with Claude Code