0Pricing
Claude Architect · Lesson

Deterministic Enforcement vs Prompts

Hooks are 100% certain; prompts are ~90% probable.

Deterministic Enforcement vs Prompts is a free Claude Architect lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Claude Architect learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.

Two Ways to Enforce a Rule

When you need an agent to always follow a rule, you have two fundamentally different tools.

  • Prompts ask the model to behave a certain way. The model usually complies — but it's still a probabilistic system making a judgment call.
  • Hooks are deterministic code that runs around tool calls. They don't ask — they enforce.

This lesson teaches the single most important number in workflow enforcement: a well-written prompt gives you roughly ~90% compliance; a hook gives you 100%.

Prompts Are Probabilistic

A system prompt is guidance. Even an excellent one — explicit criteria, few-shot examples — steers the model toward the right behavior but never guarantees it.

Across thousands of requests, that residual ~10% surfaces: an edge case, an unusual phrasing, a long context where the rule sits in the lost-in-the-middle zone. The model generalizes from your instructions, which is exactly why it can also generalize wrong.

For most behaviors that's fine. For rules where a single violation is unacceptable, ~90% is a liability.

system = (
    "You are a refund agent. "
    "NEVER issue a refund above $500 without manager approval."
)
# This is guidance. The model will *usually* obey —
# but 'usually' is not 'always'. There is no code path
# that physically blocks a $501 refund.

Hooks Are Deterministic

A hook is ordinary code wired into the agent lifecycle. It runs every time, evaluates a condition the same way every time, and its decision does not depend on model reasoning.

  • PostToolUse hooks intercept a tool's result before the model ever sees it.
  • Outgoing-call hooks block policy-violating actions before they execute.

Because the logic is hard-coded, the guarantee is absolute: 100% deterministic enforcement. A blocked action is blocked — no matter what the model decides.

def block_large_refund(tool_name, tool_input):
    if tool_name == "process_refund" and tool_input["amount"] > 500:
        return {"allow": False,
                "reason": "Refunds over $500 require manager approval"}
    return {"allow": True}
# Runs on EVERY process_refund call. $501 is blocked, every time.

The Decision Rule

Here is the rule to memorize for the exam and for real architecture:

Use hooks when failure has financial, legal, or safety consequences.

If a single violation costs money, breaks the law, or endangers someone, ~90% is not acceptable — you need 100%. That is a hook's job. Prompts are for guidance, tone, preference, and the countless soft behaviors where an occasional miss is recoverable.

Don't enforce a critical business rule with prompts alone. That is one of the most common wrong answers on scenario questions.

Programmatic Preconditions

The same deterministic principle applies to preconditions — rules about what must happen before an action is allowed.

Example from the Customer Support scenario: never run process_refund until get_customer has returned a verified customer ID. You could write that as a prompt instruction... or you could enforce it in code so it physically cannot be skipped.

A programmatic precondition gives a deterministic guarantee that prompt guidance cannot. The identity check happens 100% of the time, not 90%.

def require_verified_identity(tool_name, tool_input, state):
    if tool_name == "process_refund" and not state.get("verified_customer_id"):
        return {"allow": False,
                "reason": "Block refund until get_customer returns a verified ID"}
    return {"allow": True}

Why Not Just Prompt Harder?

A tempting trap: "I'll write a really strong prompt — all caps, repeated three times, with examples." This improves compliance, but it does not change the category. You are still on the probabilistic side of the line.

Few-shot examples and explicit criteria are powerful — they raise quality, reduce hallucination, and lock in output format. But they raise the ceiling of ~90%; they never reach the deterministic 100% that financial, legal, and safety rules demand.

If the requirement is a guarantee, no amount of prompt engineering substitutes for code.

Hooks Don't Replace Model Decisions

Important balance: hooks are not a license to hard-code everything. The agentic loop is model-driven — the model decides which tools to call and when, based on stop reasons.

You reserve hard code for guarantees, not for routine decision-making. Think of it as a thin, deterministic safety boundary around an intelligent, flexible core.

The same wisdom appears with iteration caps: a cap is a safety net, never the primary stop mechanism. Terminate on stop_reason, and use deterministic code only where a hard guarantee is genuinely required.

PostToolUse: Guarding Inputs to the Model

A PostToolUse hook intercepts a tool result before the model sees it. This is more than blocking — it's a deterministic checkpoint on data flowing back into the conversation.

Use it to enforce things like: redact secrets from output, validate that a required field is present, or refuse to surface a result that violates policy. Because it runs deterministically on every result, the model never even gets a chance to mishandle data you've decided it must not see raw.

def post_tool_use(tool_name, result):
    if tool_name == "lookup_order":
        # Deterministically strip PII before the model sees it
        result.pop("raw_credit_card", None)
    return result

Outgoing-Call Hooks: Guarding Actions

The mirror image of PostToolUse is the outgoing-call hook: it sits between the model's decision to act and the action actually firing.

This is where you block policy-violating actions — the refund over $500, the email to an unapproved domain, the deletion of a protected resource. The model may request the action; the hook decides whether it executes.

This separation is the architecture: the model proposes, deterministic code disposes — but only for the small set of rules that truly require a guarantee.

def on_outgoing_call(action):
    if action.type == "refund" and action.amount > 500:
        raise PolicyViolation("Refund exceeds $500 ceiling")
    if action.type == "refund" and not action.customer_verified:
        raise PolicyViolation("Customer identity not verified")

Reading the Signal in a Scenario

Exam scenarios telegraph the answer with their wording. Train yourself to spot it:

  • Words like "must never," "financial," "compliance," "safety," "regulatory," or a hard dollar threshold → the answer involves a hook / deterministic enforcement.
  • Words like "prefer," "tone," "style," "usually," "when appropriate" → a prompt is fine.

If an option proposes enforcing a hard, costly rule with "a stronger system prompt," it is almost certainly a distractor.

Combine Both Layers

The strongest designs use both. The prompt makes the model want to do the right thing 90% of the time — fewer blocked attempts, smoother conversations, better UX. The hook catches the remaining 10% with a hard guarantee.

Prompt for good default behavior; hook for the non-negotiable boundary. You get a system that is both intelligent and provably safe — guidance for the common case, deterministic enforcement for the catastrophic one.

# Layer 1 (prompt, ~90%): set the right default behavior
system = "Confirm customer identity before any refund, and keep refunds under $500."

# Layer 2 (hook, 100%): the guarantee the prompt can't make
hooks = [require_verified_identity, block_large_refund]

Quick Check: Refund Policy Enforcement

Apply the decision rule to a real scenario.

Recap: 100% vs ~90%

Key takeaways:

  • Prompts are ~90% probabilistic guidance; hooks are 100% deterministic enforcement.
  • Use hooks when failure has financial, legal, or safety consequences; use prompts for tone, preference, and soft behavior.
  • PostToolUse hooks guard results before the model sees them; outgoing-call hooks block policy-violating actions before they fire.
  • Programmatic preconditions (block a refund until identity is verified) give guarantees prompts cannot.
  • Reserve hard code for guarantees — keep the loop model-driven, and combine a good prompt (default behavior) with a hook (hard boundary).
  • Distrust any answer that enforces a critical, costly rule with "a stronger prompt" alone.

Frequently asked questions

Is the “Deterministic Enforcement vs Prompts” lesson free?

Yes — the full text of “Deterministic Enforcement vs Prompts” is free to read here on the web, and the Claude Architect course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Claude Architect course, upgrade to CoddyKit PRO.

What will I learn in “Deterministic Enforcement vs Prompts”?

Hooks are 100% certain; prompts are ~90% probable. You practise Claude Architect with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.

Do I need any experience to start Claude Architect?

No prior experience is required. Claude Architect on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.

How long does the “Deterministic Enforcement vs Prompts” lesson take?

Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.

Can I write and run code in this Claude Architect lesson?

Yes. Every Claude Architect lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.

All lessons in this course

  1. PostToolUse & Outgoing-Call Hooks
  2. Deterministic Enforcement vs Prompts
  3. Programmatic Preconditions
  4. Structured Handoff Protocols
← Back to Claude Architect