DEV Community

YuhaoLin2005
YuhaoLin2005

Posted on

Your AI Agent's Best Work Produces Zero Output — And That's the Point

My Stop hook produces nothing. No "all good." No "checks passed." Complete silence. And that's exactly how I designed it.

Most AI monitoring is noisy. Every hook prints something. "Session complete!" "All checks passed!" "Health: green." Multiply by 5 hooks × 30 sessions, and you've burned your context window on noise nobody reads.

Worse: when everything always says "good," you stop reading. Then the one time something breaks, you miss it.

The Unix Philosophy Nobody Applied to AI Monitoring

Unix commands are silent on success. cp doesn't print "file copied successfully!" ls doesn't announce "directory listed!" They just do their job and shut up.

This isn't laziness. It's a design philosophy: normal operations should be invisible. Only anomalies deserve attention.

The rationale is practical: when every command prints a success message, important error messages drown in a sea of false reassurance. Silence isn't absence of information — it's the absence of noise.

But AI monitoring tools adopted the opposite pattern. Every hook prints output. Every check announces its result. Every session ends with a wall of green lights that nobody reads.

The Fix: Communicate via Exit Code, Not Stdout

delivery-gate's two hooks follow Unix conventions:

# Normal path: exit 0, zero output
python3 ~/.claude/scripts/config-health.py --hook
# → (nothing printed, context window untouched)

# Anomaly path: exit 1-2, concise output
python3 ~/.claude/scripts/quality-gate.py
# → "BLOCK: 3 libraries stale (growth-log, decisions, output-index)"
Enter fullscreen mode Exit fullscreen mode

The key insight: the hook communicates via exit code. 0 = proceed. Non-zero = something's wrong. stdout is reserved for human-readable diagnostics — and only when something actually needs attention.

Three design decisions make this work:

  1. Deterministic checks only. Regex patterns and file modification timestamps. No AI inference. The check can't hallucinate — and it completes in milliseconds.
  2. Zero-token normal path. config-health.py always exits 0 (process monitoring is soft). quality-gate.py exits 0 when everything's fresh (output enforcement is hard). Neither prints anything on success.
  3. Separation of concerns. config-health tracks process (rules, verifications, config integrity). quality-gate enforces output (five-library freshness, disk space). Two layers, one job each. Neither tries to do everything.

The Double-Layer Design

A single-layer gate is either too soft (reminders → ignored) or too hard (frequent blocks → bypassed). Two layers each do one thing:

Layer Problem Method Blocks?
config-health Doing it right Counts rule markers Never (advisory only)
quality-gate Done doing it Checks file freshness ≥3 stale → hard block

The boundary isn't "importance" — it's "can this be fixed later?" Missed rule execution can be retroactively marked. Missed output records are lost forever. Process is soft. Output is hard.

What Happened

I haven't seen a hook output in two weeks. Not because nothing's wrong — because the system only speaks when something is.

Last week quality-gate blocked a session: disk space below 15GB. If it had been printing "disk: OK" every session, I would have mentally filtered it out. But because it's silent 99% of the time, the one alert was impossible to miss.

The General Principle

Normal paths should be silent. Anomaly paths should be loud. The silence-to-noise ratio defines whether anyone actually reads the alerts.

This applies beyond AI config. Your monitoring dashboard — how many green boxes do you scroll past to find the one red one? Your CI pipeline — how many "build successful" emails have you archived without reading? Your code review checklist — how many "looks good" comments are auto-pilot?

Silence isn't missing information. It's making room for the information that matters.

Try It Yourself

Check your hooks. Look at every "all good" or "success" output:

# Find noisy hooks
grep -r "success\|passed\|all good\|complete" ~/.claude/settings.json
Enter fullscreen mode Exit fullscreen mode

Delete the success messages. Keep only the error paths. Your future self will actually read the errors.


delivery-gate is a dual-layer mechanical gate for Claude Code. Two Python scripts, zero dependencies, MIT licensed. Deep dive at checkgrow.


This article is part of the *Engineering Trustworthy AI Output** series:*

Top comments (0)