monitor
Skill12 starsChanged 7 months agoMITView on GitHub
Run a bounded, self-checking polling loop (sleep -> check -> decide, repeat) WITHOUT ENDING THE TURN. The turn ends only when the watched thing is done, has failed, or genuinely needs the user's attention — which is what makes Amplifier's end-of-turn notification fire correctly and honestly. Primarily invoked explicitly via `/monitor <thing to watch>`, e.g. `/monitor the CI run for PR 412, check every 2m, stop after 1h`. May also be self-invoked in the rare case you are about to tell the user "I'll keep working and let you know" for something with a genuinely checkable, bounded condition — see the self-invocation guard below before doing that. For continuous multi-lane parallel work toward an outcome, see the ten-lane-highway skill (ships with the Amplifier CLI).
We split this skill into the rules it gives an agent
12 rules. 0 are common, 11 are distinctive, and 1 is very specific to this project.
0
Common
Most of the 24 edited versions we read keep these.
11
Distinctive
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 31
Do not do that.
- Distinctive: line 35
Only start this loop on your own initiative if ALL of the following hold:
- Distinctive: line 43
If any of those don't hold: do a single check and stop, or ask the user what "done" means.
- Distinctive: line 50
Before the first sleep, make sure you can state all four (ask the user only if truly ambiguous -- most of the time $ARGUMENTS already …
- Distinctive: line 58
Never assume beyond 4h without the user explicitly saying so.
- Distinctive: line 67
Don't raise the subject.
- Distinctive: line 136
Every poll re-sends this session's ENTIRE context to the model.
- Distinctive: line 174
Put this in every delegated instruction, verbatim:
- Distinctive: line 210
When the child returns, use ITS verdict token as YOUR first line -- your final message is what becomes the notification, not the child's.
- Distinctive: line 226
Do not paste full log or command output into your visible response on every iteration.
- Very specific: line 229
Prefer small structured signals over full dumps: exit codes, grep -c <marker> file, curl -o /dev/null -w '%{http_code}', tail -n 20 instead …
- Distinctive: line 270
No semicolons -- they are stripped by the notification sanitizer.
“Common” is measured: kept by at least 6 in 10 of the 24 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Monitor
You invoked (or are about to invoke) a bounded polling loop for: $ARGUMENTS
The entire point of this skill is that your TURN does not end until one of three outcomes is reached. Ending the turn with "I'll check and let you know" instead of actually running this loop is exactly the failure this skill exists to prevent. Do not do that.
Self-invocation guard (only relevant if you were NOT explicitly told /monitor)
Only start this loop on your own initiative if ALL of the following hold:
- You were about to say something like "I'll keep an eye on it / let you know when it's done" -- i.e. you were about to make a promise you have no other way to keep once this turn ends.
- The condition is concrete and checkable right now (a command, URL, log line, process, CI status) -- not vague ("I'll think about it more").
- The user asked for ongoing follow-up, not a single point-in-time answer.
If any of those don't hold: do a single check and stop, or ask the user what "done" means. Don't silently start a multi-hour loop nobody asked for -- that burns the user's time and locks out their session just as much as no follow-up would have, just less visibly.
Step 0 -- Pin down the four parameters
Before the first sleep, make sure you can state all four (ask the user only if truly ambiguous -- most of the time $ARGUMENTS already answers this):
- WHAT to check -- exact command / URL / log path / process name / CI run id.
- DONE condition -- the concrete success signal.
- NEEDS-ATTENTION condition -- see the list below; don't invent new ones ad hoc.
- Interval and max duration.
- Defaults if unspecified: interval = 60s, max_duration = 2h.
- Never assume beyond 4h without the user explicitly saying so.
- State your interval/max_duration back to the user in one line before the first sleep, e.g.: "Checking every 60s for up to 2h." Say this ONCE, not every iteration.
Say NOTHING about whether the user can or cannot reach you mid-loop. Whether typed input is queued and delivered between iterations depends on the client, so any claim either way will be wrong somewhere -- and claiming they can't reach you pushes them toward a hard cancel when a sentence might have worked. Don't raise the subject.
Step 1 -- Decide who runs the loop. DEFAULT: a sub-agent.
Delegate the loop (Step 3 has the exact call) unless one of these holds:
- The user needs to watch progress happen, or wants to steer mid-flight.
- Judging "done" needs context only this session has.
- The whole monitor is shorter than ~1 minute -- dispatch overhead exceeds it.
Otherwise: delegate. Every inline poll re-sends this session's entire context to the model, so an inline loop in a large session is the single most expensive way to wait for something.
Either way the notification is safe: delegation BLOCKS your turn, so your turn still ends at the moment the work resolves, and sub-session completions do not fire their own ping. Exactly one notification -- yours -- at the right time.
Step 2 -- The loop itself
This is what runs. Identical whether you execute it inline or hand it to a sub-agent in the instruction. Whoever runs it does not end their turn until one of the outcomes below is reached.
iteration = 0
started = now()
loop:
iteration += 1
elapsed = now() - started
if elapsed >= max_duration:
-> STOP (timeout). Report: "No resolution after {max_duration}. Last
check showed: {one-line summary}." End your turn now.
# Wait. Prefer several SHORT bounded waits over one giant one:
# - bash `sleep` is for FINITE waits, not indefinite ones -- keep each
# sleep call <= ~120-240s regardless of your overall interval, and
# chain multiple short sleeps to reach a longer interval if needed.
# - if the thing you're watching is itself a long-running foreground
# process (a build, a server), start it with run_in_background and
# poll its output/exit status with quick foreground calls instead of
# blocking a giant sleep on it.
wait ~interval seconds this way, then:
check the thing with the NARROWEST command that answers the question --
prefer exit codes / grep -c / http status codes over dumping full content
(see token discipline below).
classify:
USER SPOKE -> If a user message appears between iterations, it
OUTRANKS the loop. Honor it immediately -- do not
finish the cycle first, do not "just do one more
check." (Whether this can happen depends on the
client; handle it if it does, don't count on it.)
stop/pause -> STOP now, report state, end turn.
change -> adopt the new interval/target/
condition and continue looping.
question -> answer it, then say whether you're
still watching, then continue or stop.
DONE -> STOP. Summarize outcome. End your turn now.
NEEDS ATTENTION -> STOP. Explain exactly what's blocking/ambiguous and
what you need from the user. End your turn now.
NOT YET -> say nothing chatty to the user; continue the loop.Step 3 -- The delegated form (this is the DEFAULT -- see Step 1)
Every poll re-sends this session's ENTIRE context to the model. The check output is a few bytes -- the input is everything you have ever said. In a large session that input cost dominates everything else about the monitor.
Delegate the loop instead of running it inline:
delegate(
agent="self",
context_depth="none", # clean slate -- this is the entire point
model_role="fast", # polling judgment is usually mechanical
instruction="<complete, self-contained monitor spec -- see below>",
)The child pays only the bundle's system-prompt floor per poll, not this session's accumulated history.
This is safe, and the notification still lands correctly:
- Delegation BLOCKS your turn until the child returns, so your turn still ends at the moment the work actually resolves.
- Sub-session completions do NOT fire their own notification -- they're suppressed by design. The user gets exactly one ping: yours, when you relay the verdict and end your turn.
What you give up: you cannot see the child's progress, and it cannot be steered once dispatched. Everything must be in the instruction: the exact check command, the done condition, the needs-attention conditions, the interval, the max duration, the verdict-line format below, and the sequential requirement below.
SEQUENTIAL ONLY -- state this explicitly in the instruction. A child that
is told to make N checks may issue all N as parallel tool calls in a single
turn. Observed: a child asked for 15 checks emitted 15 simultaneous tool_use
blocks, so all 15 "checks" sampled the same instant. It reported success. It
had monitored nothing -- a batch of simultaneous checks can never observe a
state change.
Put this in every delegated instruction, verbatim:
SEQUENTIAL ONLY: Make ONE check, wait for its result, decide, then make the
next. Never issue multiple checks in the same turn. Never batch or
parallelize. Each check must observe the result of the previous one.A condition-driven loop ("keep checking until X") is mostly self-protecting, because check N+1 depends on seeing check N's result. A count-driven loop ("make N checks") has no such dependency and WILL be parallelized. Prefer condition-driven instructions, and state the rule regardless.
Sanity-check the result before you trust it. A real sequential monitor
costs roughly one LLM call per check and takes at least
interval x checks of wall time. If the child returns far faster or far
cheaper than that math predicts, it batched -- the result is void. Re-run it
with the sequential rule stated. Measured reference: a 13-check monitor on a
fast model took 14 LLM calls and 100 seconds. A batched 15-check imposter
took 2 LLM calls and 18 seconds, and cost a third as much. Suspiciously cheap
is the tell.
Dispatch latency is real -- measure your expectations against it. In a live
run, ~40 seconds elapsed between the parent issuing delegate(...) and the
child's first check actually executing (session spin-up plus first tool call).
Consequences:
- A delegated monitor cannot detect anything sooner than ~40s. If the thing might resolve faster than that, run inline or you will simply observe it already finished.
- The child's first check may find the condition ALREADY met. That is a legitimate DONE, not a bug -- but it means the loop never exercised. Do not report "watched for N minutes" when the child reported one immediate hit.
- Sub-minute intervals are pointless in the delegated form for the same reason they are pointless inline: per-check round-trip dwarfs the sleep.
When the child returns, use ITS verdict token as YOUR first line -- your final message is what becomes the notification, not the child's.
What counts as "needs attention" (stop and surface -- don't guess, don't grind)
- The check itself fails 2+ times in a row (distinct from the thing being watched failing) -- your monitoring mechanism is broken; don't loop blind.
- The condition is unambiguously failed (build failed, process crashed, a non-transient error) -- don't keep polling something that's already dead.
- You still can't tell done-vs-not-done after refining the check twice -- irreducible ambiguity is itself a reason to stop, not a reason to keep trying.
- Proceeding would require a destructive or irreversible decision -- never make that call unattended; stop and ask.
Token / context discipline
- Do not paste full log or command output into your visible response on every iteration. Read/check silently via tool calls; only surface a summary when you stop.
- Prefer small structured signals over full dumps: exit codes,
grep -c <marker> file,curl -o /dev/null -w '%{http_code}',tail -n 20instead ofcat. - This loop will generate many tool-call/result pairs in this session's history. That's expected and the system's compaction is explicitly designed to truncate old tool results first -- keeping each check's output small keeps compaction cheap and keeps your OWN reasoning focused.
If the system gives you an iteration-limit / wrap-up reminder
Honor it. Treat it as an effective early stop even if you haven't hit your own max_duration yet -- report status honestly, including that the turn's own iteration budget capped you sooner than max_duration, and suggest the user re-run with a longer interval / shorter max_duration next time if they want a single turn to cover more ground. Do not try to argue past a wrap-up reminder.
Escalation message shape (when you stop for DONE / NEEDS ATTENTION / TIMEOUT)
Your final message IS the notification. Verified mechanically: the desktop / terminal / phone notification body is built from the first ~100 characters of your last assistant message. Everything past that is invisible to someone glancing at a phone or a background pane -- which is the entire audience for this skill.
So the FIRST LINE must be verdict-first and under 100 characters, starting with one of exactly four state tokens:
DONE: CI green on PR 412, 318 tests passed
NEEDS YOU: deploy blocked on manual approval gate, job 4471
GAVE UP: 2h elapsed, endpoint still returning 502
PAUSED: stopped watching at your request -- run still going, 4/110 sourcesPAUSED is for when the user told you to stop watching. Be explicit that you
stopped WATCHING, not that you stopped the thing being watched -- those are
different, and confusing them will make the user think you killed their job.
Rules for that first line:
- State token first. No preamble, no "I've finished monitoring and...".
- The single most decision-relevant fact, not a summary of your process.
- No semicolons -- they are stripped by the notification sanitizer.
THEN, on following lines: what you observed (one line), how long you watched, how many checks you made. Do not restate the whole poll history.
@foundation:context/shared/common-agent-base.md
Other versions28 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 28
- NVIDIA/Model-Optimizer★ 5.5ksame name
- NVIDIA/TensorRT-Model-Optimizer★ 5.3ksame name
- H-mmer/pentest-agents★ 815same name
- elitan/frost★ 324same name
- k1p1l0/claude-telegram-supercharged★ 141same name
- block/builderbot★ 105same name
- no-session/pstack★ 96same name
- joelhooks/joelclaw★ 64same name
- rainday/smart-blog-skills★ 35same name
- freemty/labmate★ 25same name
18 more not listed
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
Used alongsideProjects with it also use spec.
Other files people use alongside this one.
Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
SentrySkillspec
Produce a verified spec — problem, desired outcome, and acceptance criteria — before building. Use when given a GitHub/Linear issue link, when starting from a fuzzy in-conversation idea, or asked to "figure out what to do" / "scope this" / "what should I build" — whenever the *what* isn't yet pinned down. Grills the ambiguities, checks the premise against the code, and produces acceptance criteria you sign off on — then hands to design-first.
Also in 3 projects that use this
In this repository32 other files it gives its agents.
- amplifier-philosophySkill
- module-developmentSkill
- python-standardsSkill
- adapt-skillSkill
- bet-sizerSkill
- bug-reportSkill
- code-reviewSkill
- council-hereSkill
- councilifySkill
- councilSkill
- cranky-old-samSkill
- create-demo-videoSkill
- crusty-old-engineerSkill
- engineering-patternsSkill
- image-visionSkill
- intent-keeperSkill
- mass-changeSkill
- outcome-cartographerSkill
- outcomistSkill
- personafySkill
- positioning-criticSkill
- product-council-hereSkill
- product-councilSkill
- restless-old-brianSkill
- retrospectiveSkill
- second-opinionSkill
- session-debugSkill
- skillifySkill
- skills-assistSkill
- tester-breakerSkill
- user-advocateSkill
- verification-disciplineSkill
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

