← Tidelines/Best practices

The pre-launch checklist for a contact-center agent

"Looks good, ship it" is not a launch gate. These are the seven questions to answer before a support agent takes its first real conversation, and every one of them is a command you can run instead of a vibe you have to trust.

by TypeGlish team8 min read#best-practices
Seven gates before you ship.

TL;DR Before a contact-center agent goes live, clear seven gates, each tied to a command: it compiles clean (check), clears a score floor (score --min B), every tool is reachable from a rule, there's one scoped escalation path, the sad paths have tests (test --dry), no rule is vaguer than you can measure, and the built artifact is what ships, pinned in CI.

Most agent launches are gated by a demo: someone runs three friendly questions, the bot answers well, and it ships. Then production sends the other traffic, the angry caller and the ambiguous refund and the message that trips two rules at once, and the prompt that "looked good" turns out to have never been checked against anything. A launch gate should be the opposite of a demo. It should try to fail the prompt on purpose, and only let it through when it can't. Here is the list we run. Each item is phrased as a question, and each question has an answer a command gives you, not a person.

§1Does it compile clean?

Gate zero: npx typeglish check exits 0. Not "no obvious problems" - zero blocking errors. This is the gate that catches the defects prose review never does: a contradiction between two far-apart rules, an unsatisfiable bound, a tool named in prose the compiler can't bind. That last one is the single most common launch-blocker we see, because it looks completely fine to a human reader.

support.tg✕ won't compile
<$CONFIG>
  $IMPORT tool escalate_to_human
</$CONFIG>

# Role
You are a support agent for an online electronics retailer.

# Escalation
- WHEN the customer mentions a chargeback THEN call escalate_to_human.
The tool is imported and the rule names it, so it reads as wired. But the name sits in bare prose, so the compiler can't bind the call.
tg check - output
support.tg:9:53  error  structure/bare-tool-ref  "escalate_to_human" is a tool, but this
  mention is bare prose - the compiler cannot bind it. Point it with
  @[escalate_to_human] (a checked reference), or quote it ("escalate_to_human") to
  speak the name as plain text.

 1 file - 1 error, 0 warning, 0 info
Exit code 1 fails the gate. The fix is one character of intent: @[escalate_to_human], a reference the compiler checks.

§2Does it clear a score floor?

Compiling clean means the prompt has no proven defects. It does not mean the prompt is good. A prompt full of vague, unmeasurable rules compiles fine and behaves terribly. The score is the second gate: pick a floor, wire it in, and let a change that drags quality below it fail the build.

tg score --min B - output
support.tg - A (94/100)  proven errors: none  tiers: base+z3
  planes  runtime 91 (what the model reads) · hygiene 100 (source only)
  facets  enforceability 77 · consistency 100 · structure 100 · annotation 100
          · style 100 · security 100

 A (94/100) clears the B floor
The floor is a policy, not a target - set it where a regression should stop a deploy. The lowest facet, enforceability, is always the honest place to look next: it measures how many rules are written as bounds a checker can defend.

§3Is every tool reachable from a rule?

An agent can only call a tool the prompt tells it to reach for. A tool that is imported but never pointed at from a rule is dead weight the model may never discover, and the checker flags it as structure/unused-import. Walk the list the other way too: every capability you promised the launch stakeholders should trace to a WHEN rule and an @[tool] pointer. If it doesn't, the agent has the tool and no reason to use it. (This failure mode has its own post: why your agent won't use the tool you gave it.)

§4Is there one escalation path, and is it scoped?

Every contact-center agent needs a clean way to hand off to a human, and exactly one. Teams accrete escalation rules - one for anger, one for legal, one for refunds over a threshold - until two of them fire on the same message and disagree about what to do. Scope each trigger with WHEN/UNLESS so no two can both fire and contradict, make the handoff a real tool call, and give it a test. The full pattern is in how to write escalation rules for an AI support agent; the launch gate is simpler: grep your prompt for every path to a human and confirm they can't collide.

§5Do the sad paths have tests?

The happy path never breaks in production; the sad paths do. Write them down as inline $TEST blocks next to the rules they exercise, then let test --dry tell you your coverage offline. Coverage below 100% is not a failure - it's a map of which rules no test protects, which are precisely the rules a future edit can break without anyone noticing.

tg test --dry - output
 support.tg  coverage: 2/4 rules exercised
  · chargeback_path - "I have already filed a chargeback with my bank." (not run)
       rubric 0.00 - not run (--dry)
  · asks_for_order - "what is the status of my order" (not run)
       rubric 0.00 - not run (--dry)
 1 prompt - 0 failed
Two of four rules are pinned. Before launch, that number is a to-do list: either the other two get a test, or you decide out loud that they don't need one. --dry is fully offline; the live run sends each case to a model.

§6Is any rule vaguer than you can measure?

"Be helpful." "Keep it reasonably short." "Use good judgment." Every one of these compiles, and every one of these constrains nothing - there is no reading a checker (or a teammate) can hold the model to. Read every rule and ask: could two people disagree about whether the agent followed it? If yes, it's a vibe, not a rule. Replace it with a bound (at most 3 sentences) or delete it. This is the whole move behind turning a prompt that reads well but scores a D into one that scores a B, which we walked through in the rewrite of a bloated support prompt.

§7Is the artifact what ships, and is it in CI?

The .tg file is source. What a model receives is the build artifact npx typeglish build writes, and that artifact - never a hand-edit, never the source - is what deploys. The last gate wires the first six into CI so they run on every edit, not just the day someone remembered the checklist: check for exit 0, score --min B for the floor, test for the sad paths, then build. A change that reintroduces a contradiction or drops below the floor fails the pipeline, and the customer never meets the regression.

support.tg - clears every gate✓ compiles · A (94/100)
<$CONFIG>
  $IMPORT tool escalate_to_human
</$CONFIG>

# Role
@@ role: scope the agent to what it owns
You are a support agent for an online electronics retailer.

# Constraints
@@ no_prices: quoted prices go stale and bind the company
- NEVER state a specific price.
@@ brevity: replies over three sentences get skimmed
- MUST keep every reply to at most 3 sentences.
@@ verify_first: the order number unlocks account context
- ALWAYS ask for the order number before discussing an order.

# Escalation
@@ chargeback: a filed chargeback is a legal matter, not a chat
- WHEN the customer mentions a chargeback THEN escalate with @[escalate_to_human].

$TEST chargeback_path
  - input:: I have already filed a chargeback with my bank.
  - expect::
    - calls the escalate_to_human tool
$TEST asks_for_order
  - input:: what is the status of my order
  - expect::
    - asks for the order number
One prompt, seven green checks: it compiles, scores an A, points at its tool, scopes its one escalation path, tests two sad paths, keeps every rule measurable, and builds. That is a launch gate a machine can hold.

None of this replaces judgment about what the agent should do - that is still your job. What the checklist replaces is the hope that you remembered everything on launch day. Seven commands, seven exit codes. Run them in CI and the gate holds itself, long after the demo that shipped the last version is forgotten.

Field note

The gates lean on capabilities from across the toolchain: the logic and structure checks shipped in TypeGlish 0.1.0 alongside the score and inline $TEST. If you only adopt one gate first, make it the score floor from the eight rules that survive production: it is the fastest read on whether a prompt is measurable enough to defend.

FAQCommon questions

What should I check before launching an AI support agent?
Turn the soft questions into checks that pass or fail. The prompt should compile with zero blocking errors, clear a quality-score floor, reference every tool it is allowed to call, have exactly one scoped escalation path, carry a test for each sad path, contain no rule vaguer than you can measure, and ship as a built artifact pinned in CI so an edit cannot regress it silently. Each of those is one command: npx typeglish check, score, test, and build.
How do I know my agent prompt is production-ready?
Production-ready means the prompt fails loudly when it is wrong, not quietly in front of a customer. Concretely: npx typeglish check exits 0 (no contradictions, no dangling tools), npx typeglish score --min B passes your floor, npx typeglish test --dry shows your critical rules are covered by a $TEST, and the whole thing runs in CI on every edit. If a change breaks a rule, the build breaks, not the customer's conversation.
What is a good pre-launch checklist for a contact-center chatbot?
Seven gates: it compiles clean, it clears a score floor, every tool it can call is reachable from a rule, there is exactly one escalation path and it is scoped, the sad paths have tests, no rule is vaguer than you can measure, and the built artifact is what ships and is checked in CI. Tie each gate to a command so the checklist runs itself instead of relying on someone remembering it.
How do I test an AI agent prompt before going live?
Write the hard cases as inline $TEST blocks next to the rules they exercise: the angry caller, the refund with no order number, the chargeback that must escalate. Run npx typeglish test --dry to validate the suite and see rule coverage fully offline, then run it live against a model before launch. Coverage below 100% tells you exactly which rules no test protects, which are the ones an edit can break unnoticed.
∿ washed up Jul 20, 2026 ∿