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

작성자

카테고리:

← 피드로
DEV Community · YuhaoLin2005 · 2026-07-01 개발(SW)

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. Measuring invisible quality signals — like compaction degradation — requires the right sensors. 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:*

What monitoring output do you check most — and what do you wish you could silence? Check your hooks. If you see “all good” or “success” in any of them, try deleting the success message and keeping only the error path.

中文版:掘金/YuhaoLin2005yhl · Code on GitHub

원문에서 계속 ↗

코멘트

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다