The Coach

Continuous observation with suggestions. The ratchet’s observation phase, automated.


The problem

The agent works. The tools are available. The mode is set. But the agent doesn’t always use what it has effectively. It searches for a function name with file_search when find_definitions would give it the answer with type information and scope. It reads files one at a time when file_read_batch would read all five in one call. It runs tests after every single edit when batching the edits and testing once would be more efficient.

The knowledge of “what to use when” currently lives in:

  • The Strategy Instruction (pattern 2) — one-time, before the task

  • The Mode Controller (pattern 7) — switches configurations on failure

Neither provides ongoing guidance. Neither says “hey, you just searched for getattr three times in different files — use find_callers('getattr') instead.”

The pattern

A hook that fires periodically (every N tool calls), analyzes recent tool usage, and injects a brief suggestion into the conversation. Not enforcement — guidance. The agent can ignore it.

What the coach observes

Using Fledgling’s conversation analytics:

  • Repeated patterns: Same search three times → suggest a batch or semantic tool

  • Tool underuse: find_definitions available but never called → suggest it when the agent is searching for function names

  • Inefficiency: Five sequential file_read calls → suggest file_read_batch

  • Anti-patterns: Editing without testing for 10 turns → suggest running tests

  • Context gaps: Agent editing evaluator.py but hasn’t read the test file that covers it → suggest reading the test

What the coach says

Short, specific, actionable:

[coach] You've called file_search("getattr") on 3 files separately.
find_callers(function_name="getattr") searches all files at once
and shows the calling context.
[coach] You've edited src/evaluator.py 4 times without running tests.
Consider run_tests() to verify before continuing.
[coach] You're reading files one at a time. file_read_batch can
read multiple files in one call:
file_read_batch(["src/tokenizer.py", "src/parser.py", "src/evaluator.py"])

What the coach doesn’t do

  • Doesn’t enforce. The agent can ignore every suggestion.

  • Doesn’t decide. The coach observes and suggests, it doesn’t change modes or tools.

  • Doesn’t use trained judgment. The suggestions are pattern-matched from the tool call log, not generated by an LLM.

  • Doesn’t slow down. Fires every N calls (not every call), brief output, no extra turns.

The grade analysis

The coach is System 3* in Beer’s VSM — the audit/monitoring function. It observes downward (watches the agent’s tool calls) and reports upward (injects suggestions). It doesn’t modify the controlled system’s configuration — that’s the Mode Controller’s job. It adds information to the agent’s context, not constraints to its tool set.

The coach is a W-axis intervention: it adds context (world coupling) that changes d_reachable. The suggestion “use find_callers instead of file_search” is information that activates different paths through the agent’s decision surface. Same mechanism as the Strategy Instruction, but continuous and context-specific.

Implementation

Via Claude Code hooks

{
  "hooks": {
    "PostToolUse": [
      {
        "command": "python3 coach.py --log-dir .claude/ --every 5",
        "description": "Suggest more efficient tool usage every 5 calls"
      }
    ]
  }
}

The hook reads the last N tool calls from the conversation log, pattern-matches against known inefficiency patterns, and prints a suggestion if one applies. Claude Code includes the hook’s output in the next turn’s context.

Via Fledgling

Fledgling already has conversation analytics (ChatToolUsage, ChatSearch). The coach queries these:

-- Detect repeated searches
SELECT tool_name, arguments->>'pattern' as pattern, count(*) as times
FROM recent_tool_calls(5)
WHERE tool_name = 'file_search'
GROUP BY ALL
HAVING count(*) >= 3;

If the query returns results, the coach suggests the semantic alternative.

Via blq

For build/test patterns, the coach queries blq:

-- Detect edit-without-test pattern
SELECT count(*) as edits_since_last_test
FROM recent_tool_calls(20)
WHERE tool_name LIKE 'file_edit%'
AND sequence_number > (
    SELECT max(sequence_number) FROM recent_tool_calls(20)
    WHERE tool_name = 'run_tests'
);

The ratchet connection

The coach IS the ratchet’s observation phase, running continuously. Every suggestion is a data point: “the agent didn’t know to use find_callers.” Over time, these data points tell you:

  • Which tools the agent underuses (need better descriptions or strategy instructions)

  • Which patterns recur (candidates for combinators or new tools)

  • Which suggestions the agent follows vs ignores (the followed ones become part of the strategy instruction; the ignored ones may be wrong)

The coach feeds the Quartermaster: “agents working on bug-fix tasks use file_search 3x more than find_callers, even when find_callers is available.” The Quartermaster’s next kit revision promotes find_callers to the default set and adds a strategy hint.

Integration architecture

The Coach connects the tool ecosystem. Each tool provides observation data; the Coach synthesizes and suggests.

Fledgling (code intelligence)
  ├─ ChatToolUsage → which tools the agent used
  ├─ CodeStructure → what code the agent should be reading
  ├─ FindDefinitions → semantic alternatives to grep
  └─ ChatSearch → what the agent was looking for

blq (build/test intelligence)
  ├─ events → build failures, test results
  ├─ errors → structured error data
  └─ output → raw logs for pattern detection

jetsam (workflow intelligence)
  ├─ status → current git state
  ├─ diff → what's changed
  └─ log → commit history

Coach (synthesis layer)
  ├─ observes all three via their query interfaces
  ├─ pattern-matches against known inefficiency patterns
  ├─ suggests via Claude Code hooks
  └─ logs suggestions + whether agent followed them (ratchet data)

Example integration flows

Agent searching inefficiently:

Agent calls: file_search("def get_user", path="src/")
Agent calls: file_search("def get_user", path="src/models/")
Agent calls: file_search("def get_user", path="src/services/")

Coach observes (via Fledgling ChatToolUsage):
  3 sequential searches for the same function name

Coach suggests:
  "find_definitions(name_pattern='get_user') searches all files
  at once and returns the definition with its file, line, and type."

Agent editing without testing:

Agent calls: file_edit("src/auth.py", ...)
Agent calls: file_edit("src/models.py", ...)
Agent calls: file_edit("src/routes.py", ...)
... (no run_tests for 8 edits)

Coach observes (via blq event stream):
  8 edits since last test run

Coach suggests:
  "You've edited 3 files without running tests.
  Consider: blq run test (or run_tests) to verify."

Agent working on stale context:

Agent reads: src/auth.py (20 turns ago)
Agent edits: src/models.py (references auth.py)

Coach observes (via jetsam diff):
  auth.py changed on disk since the agent last read it
  (another process or a previous edit changed it)

Coach suggests:
  "src/auth.py has changed since you last read it (turn 12).
  You're editing models.py which imports from auth.
  Consider re-reading auth.py for current state."

Self-improvement: the meta-ratchet

The Coach logs every suggestion and tracks whether the agent followed it:

-- Coach effectiveness over time
SELECT suggestion_type,
       count(*) as times_suggested,
       sum(CASE WHEN followed THEN 1 ELSE 0 END) as times_followed,
       round(avg(CASE WHEN followed THEN 1.0 ELSE 0.0 END), 2) as follow_rate
FROM coach_suggestions
GROUP BY suggestion_type
ORDER BY follow_rate DESC;

Suggestions with high follow rates are good — they become candidates for the Strategy Instruction pattern (bake them into the prompt). Suggestions with low follow rates are either wrong (remove them) or correct but ignored (escalate to the Mode Controller).

This is the ratchet applied to the Coach itself:

  1. Observe: Log all suggestions and outcomes

  2. Capture: Identify which suggestions work

  3. Crystallize: High-follow-rate suggestions become strategy instructions or kit defaults

  4. Teach: The Coach gets better at knowing when to suggest what

The anti-pattern: the backseat driver

A coach that fires on every tool call, provides long explanations, or second-guesses the agent’s decisions adds noise without value. The agent stops reading the suggestions. The output tokens increase. The cost goes up.

The coach should be:

  • Infrequent: Every 5-10 calls, not every call

  • Brief: One or two lines, not a paragraph

  • Specific: Name the tool and the pattern, not general advice

  • Ignorable: A suggestion, not a requirement

The model-dependent coach

The Coach should adjust its behavior per model, just like the Strategy Instruction:

Model

Coach behavior

Why

Haiku

More frequent (every 3-5 calls), simpler suggestions

Haiku benefits from guidance and needs it more often

Sonnet

Standard frequency (every 5-10 calls), full suggestions

Sonnet follows good suggestions and ignores bad ones

Opus

Rare (every 10-15 calls), action-oriented only

Opus over-analyzes. Coach suggestions about “understanding” make it worse. Only suggest action: “run tests now” not “consider reading X”

This connects to the Quartermaster: the Quartermaster configures the Coach’s aggressiveness alongside the tool set and strategy instruction. The Coach is part of the kit.