no-sycophancy

May 17, 2026 · View on GitHub

tests License: Apache 2.0 Claude Code

A Claude Code Stop hook that blocks praise-spam at the opening of an assistant turn — "Great question!", "You're absolutely right!", "That's a brilliant observation!" — so the model leads with the substantive answer instead of validation theater.

no-sycophancy is one bash file (~70 lines, depends only on jq) wired into Claude Code's Stop and SubagentStop events. It inspects the first 240 characters of every outgoing assistant message and pattern-matches the praise-spam vocabulary that LLMs default to at turn-open. When matched, it blocks with a repair-guidance template that tells the model to lead with the answer, not the compliment.

If the operator explicitly asked for praise or encouragement this turn, the hook stays out of the way — it looks for an allow-clause where the model is restating the request ("you asked for encouragement — here are…").

Why this exists

Sycophancy is the most-prevalent dark pattern in current LLMs:

In-context defenses (system prompts saying "do not be sycophantic") can drift over long sessions. The model should not be the only judge of its own sycophancy, so this hook moves the verdict path outside the model context.

Differentiation from existing anti-sycophancy tools

ToolMechanismLimitation
FutureSpeakAI/anti-sycophancyRuntime circuit breaker + system-prompt calibrationLives in-context; model can drift past it
0xcjl/anti-sycophancyThree-layer Claude Code skillSkill-based — depends on the model invoking the skill
no-sycophancyStop hook (bash, out-of-band)Catches the configured linguistic signature at turn-end; no LLM call decides the verdict

The three approaches are complementary, not competitive. Run them all if you want defense-in-depth.

Install (30 seconds)

claude plugin marketplace add waitdeadai/claude-plugins
claude plugin install llm-dark-patterns@waitdeadai-plugins

This installs the whole llm-dark-patterns suite (28 hooks including no-sycophancy).

The Anthropic community marketplace currently does not list this plugin despite a Published submission — pipeline stalled since 2026-05-13. Tracking: #1887. The self-hosted route bypasses that pipeline.

Standalone (single hook, manual wire)

mkdir -p .claude/hooks
curl -fsSL https://raw.githubusercontent.com/waitdeadai/no-sycophancy/main/no-sycophancy.sh \
  -o .claude/hooks/no-sycophancy.sh
chmod +x .claude/hooks/no-sycophancy.sh

Then merge the hook entries from settings.example.json into your .claude/settings.json.

Requires jq.

What gets blocked

Praise-spam vocabulary at message open (first 240 chars), including:

  • Great/Excellent/Brilliant/Perfect/Amazing/Fantastic/Wonderful question[!.]
  • That's a (great/excellent/perfect/brilliant/wonderful/fantastic/amazing/fascinating/really good/very good/terrific) question
  • You're absolutely right[!.,], You're correct[!.,]
  • Absolutely[!.,], Of course[!.,]
  • Excellent (point/observation/catch)[!.,]
  • Great (point/catch/observation/insight/thinking)[!.,]
  • Perfect[!.,], Brilliant[!.,], Wonderful[!.,], Amazing[!.,], Fantastic[!.,]
  • What an (excellent/amazing/insightful/thoughtful) question
  • Glad you asked, Happy to help with that

The full regex is in no-sycophancy.sh — search for SYCOPHANCY=.

What stays allowed

  • The substantive use of any of those words not at message open. The hook only inspects the first 240 chars.
  • Operator-requested praise — when the message restates a request like "you asked for encouragement" or "since you wanted feedback," the allow-clause fires and the hook stays silent.
  • Any message that opens with the actual answer, even if it later contains praise vocabulary in a substantive context ("Brilliant is the right adjective for that approach because…").

Physics-backed engine

This standalone hook remains the simplest install path. For users who want the benchmark-backed, rule-pack-hashed engine version, the same closeout mechanic is also available in AgentCloseoutBench:

git clone https://github.com/waitdeadai/agent-closeout-bench
cd agent-closeout-bench
bash adapters/claude-code/install.sh /path/to/your/project no-sycophancy
bash scripts/hook-smoke.sh

The physics-backed adapter maps no-sycophancy to the sycophancy category engine and can be used for daily enforcement, fixtures, benchmark evaluation, and opt-in content-free collaboration telemetry. The AgentCloseoutBench installer also writes a PreToolUse tamper guard for ordinary Claude Code edits to hook wiring, adapter env, pinned engine, and pinned rule-pack paths.

This keeps the standalone hook simple while making the research lane stricter: no-sycophancy remains its own category engine inside the shared Rust runtime. The tamper guard is not an OS sandbox and should not be described as bypass-proof.

Sister tools

Part of the LLM Dark Patterns Hooks suite — single-purpose Stop hooks that suppress LLM dark-pattern defaults so power-user operators can actually work.

  • no-vibes — false-success closeouts
  • time-anchor — training-cutoff date confusion
  • no-curfew — unsolicited rest/wellness paternalism
  • no-cliffhanger — dangling permission-loop endings
  • honest-eta — vibe time estimates and linear-scaling parallelism claims.
  • no-fake-recall — false-memory recall claims without quoted prior content.
  • no-fake-stats — fabricated percentages and amounts without source.
  • no-fake-cite — academic citation patterns without verifiable URL.
  • minmaxing — the parent governance harness

License

Apache-2.0. See LICENSE.