Phase 14 · Lesson 35 of 54

Initialization Scripts for Agents

Every session that starts cold pays a tax. The agent reads the same files, retries the same probes, and rediscovers the same paths. An init script pays the tax once and writes the answers into state.

Lesson 35 of 54Build~45 minutesPython (stdlib)

Before this: Lesson 32 of Phase 14 (Minimal Workbench), lesson 34 of Phase 14 (Repo Memory)

On this page

Learning Objectives

  • Identify the work an agent should never have to redo per session.
  • Build a deterministic init script that probes runtime, dependencies, and repo health.
  • Persist the probe result so the agent reads it instead of re-running checks.
  • Fail loud, fast, and with one place to look when initialization fails.

The Problem

Open a session. The agent guesses the Python version. Guesses the test command. Lists the repo root five times to find the entry point. Tries to import a package that is not installed. Asks the user where the config file lives. By the time it makes a real edit, ten thousand tokens have gone to setup work that should have been a single script.

The fix is one initialization script that runs before the agent does anything else and writes a init_report.json the agent reads at startup.

The Concept

Diagram (opens full size)

What the init script probes

Probe Why it matters
Runtime versions Wrong Python or Node version means silent wrong-version bugs
Dependency availability A missing package later costs ten times the cost of catching it now
Test command The agent must know how to verify; if the command is missing the workbench is broken
Repo paths Hard-coded paths drift; resolve them once and pin
Environment variables Missing OPENAI_API_KEY is a failure surface, not a runtime mystery
State + board freshness Stale state from a crashed session is a footgun
Last-known-good commit Anchor for the handoff diff at the end of the session

Fail loud, fail fast, fail in one place

A probe failure means halt and surface to the human. No "the agent will figure it out." The whole point of init is to refuse to start when the workbench is broken.

Idempotent

Run it twice in a row. The second run should be a no-op except for a fresh timestamp. Idempotency is what lets you wire the script into CI, hooks, or a pre-task slash command.

Init versus startup rules

Rules (Phase 14 · 33) describe what must be true to act. Init is the script that establishes that those rules can be checked. Rules without init become "be careful." Init without rules becomes a polished failure.

wb-init-probes

Build It

code/main.py implements init_agent.py:

  • Five probes: Python version, listed dependencies via importlib.util.find_spec, test command resolvability, required env vars, state file freshness.
  • Each probe returns (name, status, detail).
  • The script writes init_report.json with the full probe set and exits non-zero if any block-severity probe fails.

Run it:

python3 code/main.py

The script prints the table of probes, writes init_report.json, and exits zero on the happy path or non-zero with a list of failed probes.

Production patterns in the wild

Three patterns separate a useful init script from a ceremony.

Last-known-good commit anchoring. Probe the current commit against a LKG file written on the last successful merge. If the diff exceeds a budget (default 50 files), refuse to start and require a human to ratify the new baseline. This is what Cloudflare's AI Code Review uses to scope reviewer agents: every review session anchors against the same last-known-good and never compounds drift across sessions.

Lock files with TTL. Write a prereqs.lock after the first successful probe pass. Subsequent runs trust the lock for N hours (24h default) and skip the expensive probes. The init script reads the lock first; if it is fresh and the dependency manifest hash matches, it short-circuits. This is the same pattern Docker uses for layer caches: idempotent probe + content hash = skip.

No network, no LLM, no surprises in the hot path. Init probes are deterministic plumbing. A probe that calls an LLM to classify a failure or that hits an external service to check a license is not a probe; it is a workflow. If a probe takes longer than three seconds in a dry run, treat that as a workbench smell and either move it out of init or cache its result.

Use It

In production:

  • Claude Code hooks. pre-task hook calls the init script and refuses to launch the agent if it fails.
  • GitHub Actions. A setup-agent job runs the init script; the agent job depends on it.
  • Docker entrypoint. The agent container runs the init script before exec-ing the agent runtime; logs surface on failure.

The init script is portable because it makes no calls to a specific framework. Bash, Make, or a tasks file can all wrap it.

Ship It

outputs/skill-init-script.md interviews the project, classifies its setup work into probes, and emits a project-specific init_agent.py plus a CI workflow that runs it before any agent step.

Exercises

  1. Add a probe that diffs the current commit against the last-known-good commit and refuses to start if more than 50 files changed.
  2. Wire the script to write a prereqs.lock file and refuse to start if the lock is older than seven days.
  3. Add a --fix flag that auto-installs missing dev dependencies but never modifies runtime dependencies without approval.
  4. Move probes from hardcoded functions to a YAML registry. Defend the trade-off.
  5. Add a timing budget per probe. A probe that runs longer than three seconds is a workbench smell.

Key Terms

Term What people say What it actually means
Probe "A check" A deterministic function returning (name, status, detail)
Init report "Setup output" JSON written next to state with the probe results
Idempotent "Safe to re-run" Two runs in a row produce identical reports modulo timestamp
Fail loud "Don't swallow" Halt and surface to the human; no silent fallback
Setup tax "Bootstrap cost" The tokens the agent spends per session rediscovering the obvious

Further Reading

Check yourself

Quick quiz

  1. What does an init script eliminate?

    1. Authn tokens
    2. Provider rate limits
    3. Latency from inference
    4. The per-session setup tax: probing runtime, listing the repo, retrying the same checks each new session
    Show the answer

    D. The per-session setup tax: probing runtime, listing the repo, retrying the same checks each new session The script pays the tax once and writes the answers into init_report.json the agent reads.

  2. What is the init script's failure-mode contract?

    1. Fail loud, fail fast, fail in one place; refuse to start when the workbench is broken
    2. Always succeed
    3. Retry forever
    4. Fail soft and continue
    Show the answer

    A. Fail loud, fail fast, fail in one place; refuse to start when the workbench is broken The whole point is to refuse to start when the workbench is broken; silent fallback defeats the purpose.

  3. Which is NOT one of the probes the lesson lists?

    1. Token-by-token sampling temperature
    2. Test command resolvability
    3. Dependency availability
    4. Runtime versions
    Show the answer

    A. Token-by-token sampling temperature Probes include runtime versions, deps, test command, paths, env vars, state freshness, last-known-good commit.

  4. Why does the lesson say init must be idempotent?

    1. It satisfies SOC 2
    2. It is required by JSON Schema
    3. Idempotence saves money
    4. Running it twice should be a no-op except for a fresh timestamp, so it can be wired into CI, hooks, or a pre-task slash command
    Show the answer

    D. Running it twice should be a no-op except for a fresh timestamp, so it can be wired into CI, hooks, or a pre-task slash command Idempotence makes init safe to call from many entry points (hooks, CI, slash command).

  5. What is last-known-good commit anchoring?

    1. The earliest commit in the repo
    2. Probe the current commit against an LKG file; refuse to start if the diff exceeds a budget without human ratification
    3. The most recent commit by the team lead
    4. The merge base of HEAD and main
    Show the answer

    B. Probe the current commit against an LKG file; refuse to start if the diff exceeds a budget without human ratification Cloudflare's AI Code Review scopes reviewers against the LKG to prevent drift compounding across sessions.

  6. What does the lock file with TTL pattern do?

    1. Writes prereqs.lock after a successful probe pass; subsequent runs trust the lock for 24h and skip expensive probes if the manifest hash matches
    2. Locks the repo from edits
    3. Disables CI
    4. Blocks all writes for 24 hours
    Show the answer

    A. Writes prereqs.lock after a successful probe pass; subsequent runs trust the lock for 24h and skip expensive probes if the manifest hash matches Same shape as Docker layer caches: idempotent probe + content hash = skip.

  7. What should NEVER appear in the init hot path?

    1. Network calls, LLM calls, external license checks; probes are deterministic plumbing under three seconds
    2. Reading the lockfile
    3. Local filesystem reads
    4. Reading env vars
    Show the answer

    A. Network calls, LLM calls, external license checks; probes are deterministic plumbing under three seconds A probe that calls an LLM is a workflow, not a probe; keep init deterministic.

Questions people ask

Why do AI coding agents waste time at the start of each session?

They start with no knowledge of the environment, so they probe for versions, commands and file locations, often repeatedly. A startup script that records these facts in a file lets the agent read them in one step.

What should an agent startup script check?

Common checks are the runtime version, installed dependencies, required settings, whether the test command works, and the state of the repository. It should save results in a predictable file and stop with a plain error message if something critical is missing.

Next lessonScope Contracts and Task BoundariesPrevious: Repo Memory and Durable State

Lessons from AI Engineering from Scratch by Rohit Ghumare and contributors, MIT license. Notes for owners by Lozo. License

Next step

Rather have it built for you?

Reading is optional. Tell me what's stuck and I'll build it into the business you already run.

  • A real conversation, not a pitch
  • You keep your accounts
  • Nothing sends without your yes