g-eskayo/marvin/safety-monitor
- community
Checking that the SKILL.md file is still in the repository.
Calibrated verifier that scores an autonomous loop's output for risk (fabricated references, unsupported claims) before it ships, quarantining flagged artifacts for review instead of blocking the loop. Use when wiring a new autonomous/background loop, reviewing quarantined items, or asked about the safety/drift monitor.
Install
npx vskill@latest install g-eskayo/marvin/safety-monitorSKILL.md
Safety Monitor
Phase 1 only (see DESIGN.md for the full rollout plan). This covers pure-generation loops — scoring an artifact's text against a loop-specific rubric and quarantining it if it looks risky. The dual-channel drift audit (otr_log.py, drift_report.py) described in ARCHITECTURE.md is not built yet — don't reference those scripts as if they exist.
What this actually does
verify.py sends an artifact + a loop-specific rubric to a cheap model (haiku) and gets back a risk score in [0, 1]. calibrate.py picks the threshold (tau) that decides pass vs. quarantine — a conservative default (0.3) until at least 20 labeled examples exist for that loop, then a risk-controlled threshold computed from real approve/deny labels. Anything over tau lands in ~/.claude/quarantine.md instead of shipping silently.
This is a library, not a cron job — verify.py and calibrate.py are meant to be called synchronously from inside an existing loop script, right before it writes its output. Nothing runs on a schedule yet.
Scripts
| Script | Purpose | |
|---|---|---|
scripts/verify.py | verify(text, loop_name) -> float risk score; quarantine(...) writes a flagged item; pass_or_quarantine(text, loop_name) -> bool is the one-line integration point | |
scripts/calibrate.py | get_tau(loop_name) -> float; calibrate(...) recomputes tau from labeled data; record_label(loop_name, score, label) for when a review workflow exists to call it | |
scripts/rubrics/daily_digest.md | Rubric for improve/scripts/daily_digest.py's output | |
scripts/rubrics/research_colony.md | Rubric for research-colony/scripts/research_digest.py's output | |
scripts/rubrics/self_improve.md | Rubric for the retrospective-log.md line background_review.py appends | |
scripts/rubrics/improvement_sweep.md | Rubric for improvement_sweep.py's queue entries — checks extraction coherence (tag/message/path mismatch), not hallucination, since this loop has no LLM call |
A rubric must exist for a loop before verify() can score it — verify() raises (and fails open, returning 0.0 / "pass") if rubrics/<loop_name>.md is missing. Add a new rubric before wiring a new loop in.
Output files
~/.claude/quarantine.md— human review queue; same approve/modify/deny
convention as improvement-queue.md. No /quarantine review command exists yet — items are reviewed by reading and editing the file directly.
~/.claude/safety-monitor/tau.json— per-loop threshold, created lazily.~/.claude/safety-monitor/calibration.jsonl— labeled `{loop, score,
label} rows, created lazily by record_label(). Empty until a review workflow starts calling it — calibrate() uses DEFAULT_TAU` (0.3) until then.
Integration status
All four loops from SOURCES.md are wired in:
background_review.py(self_improve) — wired first, since it's the
highest-blast-radius one (writes directly to the git-tracked, append-only retrospective-log.md). Verification is post-hoc: snapshot the log before the review runs, diff after, score the new line(s), revert the append + quarantine if flagged.
daily_digest.pyandresearch_digest.py— wrapped the same way as each
other: pass_or_quarantine(content, loop_name="...") right before the write; on False, a short quarantine notice is written in place of the real content so the day's output file still exists (no retry-loop burning a fresh claude call on every re-run) but is clearly marked incomplete.
improvement_sweep.py— samepass_or_quarantine()wrap, but this loop
has no LLM call at all (its content is a deterministic regex/sort over a static-analysis scan), so rubrics/improvement_sweep.md checks extraction coherence (a [KIND] tag mismatched with its message, a garbled fragment, a malformed path) rather than hallucination. On quarantine, the block is simply not appended — no stub needed, since the next handoff produces a fresh (different) block rather than re-running the same one.
Manual invocation / smoke test
Triggers
- "wire safety-monitor into X", "review quarantine", "show quarantine queue"
- Session start: if
~/.claude/quarantine.mdexists with unresolved items, mention the count (not yet wired into the session-start checklist — see below)
Known gotchas
verify()'s subagent call is--tools ""plus an explicit "you have no
tool access" line in the prompt — both are load-bearing, not either alone. A rubric that asks "does this reference something that doesn't exist" invites haiku to go check by exploring the filesystem even when source_context already has what it needs, which measured 113s vs ~50-58s and blew through the old 60s timeout. See retrospective.md (2026-07-13) and the inline comment in scripts/verify.py. Keep this in mind for any new rubric-based subagent call, not just this one.
Known gaps (tracked, not silently assumed fixed)
- Session-start check for
quarantine.mdis described inREQUIREMENTS.md
(FR6) but not yet added to ~/.claude/CLAUDE.md's checklist.
- No
/quarantinereview command yet —record_label()exists but nothing
calls it, so calibrate() will sit on DEFAULT_TAU indefinitely until one is built. Expect over-flagging until then — confirmed in testing that even a well-constructed, genuinely generalizable retrospective-log entry scored above tau; that's the documented cold-start conservatism, not a bug, but it's a real cost until real labels exist.
- OTR/drift audit (
otr_log.py,drift_report.py) still not built — Phase 3.
Security
- Security scanPassed, 95 of 100Pattern checks on the skill's files.
- Model reviewPassed
Quality evaluation
- Task evaluationNot runNo evaluation yet. Run one in Skill Studio.
Source
- SKILL.md in the repositoryCheckingskills/safety-monitor/SKILL.md
Popularity
- 7-day trend score
- 5
Not refreshed yet.
Works with
Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.
- Claude Code
- Cursor
- GitHub Copilot
- Windsurf
- Codex
- Gemini CLI
- Cline
- Amp
- Roo Code
- Goose
- Continue
- Kilo Code
- Junie
- Trae
- OpenHands
- Qwen Code
- AI Agent
- Tabnine Chat
- Sourcegraph Cody
- Amazon Q
- Firebase Genkit
- Sweep
- Devin
- Phind
- Mentat
- Claude Desktop
- Aider
- GPT Pilot
- Plandex
- bolt.new
- v0
- Replit Agent
- Anse
- TypingMind
- BetterChatGPT
- LibreChat
- Warp AI
- Pieces
- Fig AI
Embed badge
[](https://verified-skill.com/skills/g-eskayo/marvin/safety-monitor)