My Profile Photo

Chang Min Park


Senior Software Engineer at Yahoo!



Hands-on lab

Agent Harness Lab

Hands-on lab for senior/mid engineers — build a tiny On-Call Triage demo site while learning harness design (loop, tools, guardrails, eval) via Claude Code. Checkboxes save in this browser.

  • ~10–14 weeks · 4–8 hr/week
  • Claude-first · optional local LLM
  • Repo: ~/demo-on-call-triage

Who this is for

You already ship software (CI, code review, least privilege). This lab maps agent harness ideas to that world — not prompt tricks.

Harness idea SWE analogue
Loop + stop gate CI must pass before merge
Tool allowlist API surface / RBAC
CLAUDE.md / rules Runbook + linter config (guidance)
Hooks / permissions Middleware + authz (enforced)
JSONL / traces Structured logs + distributed trace
Eval suite Integration tests + PR gate
Side-effect approval Production deploy approval

Goal: After the lab you can design an agent workflow on a real-shaped repo (On-Call Triage) — what the harness owns vs what the model proposes — and scaffold any path in the Claude config tree.

Minimum path (core): Phases 0–7 (~8–12 weeks part-time). Recommended: add Phase 8 (judgment). Phases 9–11 are optional depth (RAG, capstone, computer-use).


How to run this lab

Work phases top-down. Each has learn links, then todos with a How guide. Every How opens with a Point — the takeaway if you skip the steps. Checkboxes save in this browser; Optional items don’t block.

  1. Read Demo project — every phase configures On-Call Triage (demo-on-call-triage), not random snippets.
  2. Clone demo-on-call-triage to ~/demo-on-call-triage/ (Phase 0) and run Claude Code from that folder.
  3. For each phase: skim learn → do todos on On-Call Triage → demo the failure mode first → re-read the essay → pass the phase bar (check understanding: explain in one sentence).

Concepts like rules vs hooks vs guardrails and gitignore vs worktreeinclude live as collapsed notes under Phase 4 / Phase 8 How — open those todos when you reach them.

Stack: Claude Code with a Pro / Max login (claude auth login --claudeai) is the brain. Put durable agent instructions in CLAUDE.md / .claude/. Ollama / on-device and Phase 11 are optional.

Config layout: skim Config directory once, then fill it in phase by phase on On-Call Triage. Official explorer: .claude directory.


Demo project

Every lab todo applies to one repo: On-Call Triage — work in ~/demo-on-call-triage/ (clone the GitHub repo there). It is a single-page website plus one routing function. The runnable app is three files; everything else in the starter is lab scaffolding you read, not learn.

What’s in the starter clone

Piece Path Role in the lab
UI index.html One-page triage screen — needs npm run serve (ES modules are blocked over file://)
Routing logic routing.js Phase 1 bug lives here
Tests / CI signal routing.test.js, scripts/run_tests.sh Harness “done” = npm test green
Package scripts package.json npm test, npm run serve
Harness (starter) harness/observe.js Tests + optional acceptance gate → harness/ci_status.json + harness/runs/observe.jsonl
Tool-flood stub harness/junk-mcp.js Stub MCP server advertising N no-op tools (Phase 2)
Side-effect scripts/deploy.sh Fake static deploy (Phase 4)
Untrusted input tickets/INC-042.md Phase 4 injection demo
Policy docs docs/routing-rules.md Current rules + R-1…R-4 backlog the phases draw tasks from
Secrets (off limits) secrets/ Phase 3 constraint
Agent config CLAUDE.md, .claude/, .mcp.json, … You add in Phases 0–8

Run it (three commands)

npm test                 # unit tests — your CI signal (Node 18+, no install)
npm run serve            # http://localhost:3000 — required to view the UI
node harness/observe.js  # harness check → ci_status.json + runs/observe.jsonl
~/demo-on-call-triage/              ← git clone target

Starter (what you clone)
├── index.html  routing.js  routing.test.js  package.json
├── README.md
├── scripts/          run_tests.sh · deploy.sh
├── docs/             routing-rules.md
├── tickets/          INC-042.md
├── secrets/          (off limits — committed on purpose, so you can refuse to read it)
└── harness/          observe.js · junk-mcp.js

You add during the lab (not in starter)
├── CLAUDE.md  .claude/  .mcp.json  SPEC.md  plan.md
├── harness/runs/  evals/  .worktreeinclude

Clone the GitHub repo into ~/demo-on-call-triage/. Three app files + tests — then you spend the lab on harness config, not the codebase.

Starter code: clone the demo repo (not this website):

git clone https://github.com/ChangMinPark/demo-on-call-triage.git ~/demo-on-call-triage
cd ~/demo-on-call-triage && git pull   # use pull on later visits to refresh starter files

Starter includes a deliberate routing bug so Phase 1 has a real failing test. Details: demo README.

Phase → On-Call Triage work

Phase You do on On-Call Triage
0 Clone repo; Claude Code + .claude/ stub
1 Fix routing.js; wire harness/observe.js; SPEC + acceptance gate (R-1)
2 Tool allowlist vs junk-mcp.js flood on R-2; .mcp.json + deny rule
3 Full CLAUDE.md + rules/skills; prove rules are guidance only
4 Gate deploy.sh with hook/permissions (not CLAUDE.md alone); injection via tickets/INC-042.md
5 plan.md on R-4, where the rules conflict and precedence is unwritten
6 Subagents on R-3: researcher finds the R-2 dependency, coder implements
7 evals/ suite on alert scenarios
8 .gitignore vs .worktreeinclude on .env.local; overnight draft job
9–11 opt. RAG over routing docs; capstone; index.html click tests (Phase 11)

Phase roadmap

Phase You learn Essay
0 Setup Brain + config layout (fill the tree)
1 Loop Observe/stop; done ≠ CI green Done but CI red
2 Tools Allowlist; access ≠ expertise Too many tools
3 Memory Durable rules (guidance) survive cold start Forgot constraint
4 Guardrails Hooks + permissions + approvals (enforced) Trust boundaries
5 Planning Live plan vs theater Planning theater
6 Subagents Dual cost; skip rules Subagents argue
7 Eval Ship bar, not lucky chat Eval not a demo
8 Ops When agents slow you; .gitignore.worktreeinclude Slower
9 opt. RAG Wrong chunk; repo search vs RAG Wrong chunk
10 opt. Capstone Always-on without dropping gates synthesis
11 opt. UI agents Brittleness + page injection Wrong button


Stack

Think in layers. Don’t confuse a chat UI with a harness.

Layer Options Use here
Brain Claude Code (Pro/Max login) · Ollama small local model · on-device (opt.) Claude Code for real failure modes; Ollama/on-device = wiring literacy
Runtime Claude Code session + your gates · LangGraph · OpenClaw Start with Claude Code + harness scripts/hooks; graphs later
Tools / MCP Built-in tools · MCP servers · allowlists Discovery ≠ allowlist — Phase 2
Channels OpenClaw · Open WebUI · browser/computer-use Capstone / RAG / Phase 11
Observe JSONL / session logs · Langfuse · audit fields Required once you hit eval
Cost Pro usage limits · triage · when not to burn a session Treat quota/time-per-task as a harness concern
┌──────────┐     ┌─────────┐     ┌─────────┐     ┌──────────┐
│   goal   │────▶│  model  │────▶│  tools  │────▶│ observe  │
└──────────┘     └────┬────┘     └────┬────┘     └────┬─────┘
                      │               │               │
                      └───────────────┴───────◀───────┘
                                    stop?

The harness owns the loop. The model proposes; tools act; observe decides whether to stop.

LangChain/LangGraph sit in runtime — same tier as gates you write around Claude Code, not a Claude replacement.

Guidance vs enforcement: Text in CLAUDE.md / rules is guidance. Hooks, permissions, and harness scripts are enforced. Expand Phase 4’s approval-gate How for the full rules · hooks · guardrails note.


Config directory

Claude Code reads two scopes. Project files (repo root + .claude/) are what you commit for the team. ~/.claude/ is personal — same shapes, but applies across all projects on your machine. You do not need every folder on day one; the lab introduces each path when it matters.

Start with these five (Phase 0–1). Add the rest as the lab reaches them — you are not expected to memorize the full tree upfront.

Path One-line purpose
CLAUDE.md Always-on project instructions
.claude/settings.json Enforced permissions + hooks
.claude/rules/ Extra instructions (optional path scope)
.claude/skills/ Reusable /name workflows
.mcp.json Team MCP servers (root, not inside .claude/)
Full Project tree (reference — expand when needed)
project root/
├── CLAUDE.md              ← always-on instructions (or .claude/CLAUDE.md)
├── .mcp.json              ← team MCP servers (not inside .claude/)
├── .worktreeinclude       ← copy gitignored files into worktrees
└── .claude/
    ├── settings.json      ← enforced: permissions, hooks, model
    ├── settings.local.json ← your personal overrides (gitignored)
    ├── rules/             ← topic instructions (path-scoped optional)
    ├── skills/            ← /name prompts + supporting files
    ├── commands/          ← legacy single-file skills (prefer skills/)
    ├── output-styles/     ← response tone / teaching modes
    ├── agents/            ← subagent definitions
    ├── workflows/         ← saved multi-step runs
    └── agent-memory/      ← subagent persistent notes (when memory: set)

Matches the official Project tab. Personal equivalents live under ~/.claude/ (Global tab).

Two scopes, one tree: commit project paths; keep personal prefs in ~/.claude/ or settings.local.json. When the same name exists in both places, precedence depends on file type — project usually wins for settings and subagents; personal wins for skills. Full rules: settings precedence · skills.

Full path reference table (phase + scaffold commands)
Path Purpose Guidance or enforced Lab phase You create it by…
CLAUDE.md Always-on project instructions Guidance 0, 3 touch CLAUDE.md (or .claude/CLAUDE.md); expand in Phase 3
.claude/settings.json Permissions, hooks, model Enforced 0, 1, 4 mkdir -p .claude && echo '{}' > .claude/settings.json; add hooks in 1, permissions in 4
.claude/settings.local.json Personal project overrides Enforced 4 (opt.) Same JSON as settings; gitignore it — wins over shared settings.json for you
.claude/rules/*.md Topic / path-scoped rules Guidance 3 mkdir -p .claude/rules && touch .claude/rules/secrets.md
.claude/skills/name/SKILL.md Reusable /name workflows Guidance 3 mkdir -p .claude/skills/ship-checklist && touch …/SKILL.md
.claude/commands/*.md Legacy /name (single file) Guidance 3 (know) Optional touch .claude/commands/fix-issue.md — prefer skills/
.claude/output-styles/*.md Custom response styles Guidance 0 (skim) Optional mkdir -p .claude/output-styles or use /config
.claude/agents/*.md Named subagents Enforced tools scope 6 touch .claude/agents/researcher.md + frontmatter
.claude/workflows/* Saved orchestration scripts Mixed 6 (skim) Save from /workflows or stub a .js when you need multi-step reuse
.claude/agent-memory/{agent-name}/MEMORY.md Subagent notes Auto-written 6 (skim) Appears when an agent sets memory: project — you don’t hand-author
.mcp.json Team MCP server list Discovery only 2 Root touch .mcp.json or claude mcp add for personal (~/.claude.json)
.worktreeinclude Gitignored files in worktrees Enforced copy 8 Root patterns file — e.g. .env.local (must also be in .gitignore)
~/.claude/CLAUDE.md Personal instructions everywhere Guidance 0 (skim) Optional global prefs — project CLAUDE.md wins on conflict
~/.claude/skills/ Personal skills Guidance 3 (opt.) Same folder shape as project skills
~/.claude/agents/ Personal subagents Enforced tools scope 6 (opt.) Same as project agents; project wins same name
~/.claude/projects/…/memory/ Main-session auto memory Auto-written 3 Claude writes MEMORY.md — not the same as CLAUDE.md

How to create any file: from your clone root (~/demo-on-call-triage/, repo demo-on-call-triage), mkdir -p the parent folder, then add the file. Restart is usually unnecessary — Claude Code watches .claude/ changes. Confirm loads with /context (memory) or /help (skills/commands).

After the lab: you should be able to open the official directory explorer, click any Project node, and say what it does, which phase taught it, and the command you’d run to scaffold it.


Phase 0 — Setup

Topic Environment + demo-on-call-triage clone · Essay — · Prior phases none · ~4–6 hr

Copy the demo app, get Claude Code working, and stub .claude/ — every later phase extends this repo.

Learn before you build

Knowledge Why Refresh
Terminal / env vars Run scripts macOS Terminal
Git basics Version lab code Git handbook
Node.js 18+ Run tests, harness scripts Node.js
Claude Code install + Pro login Brain for this lab Claude Code setup · Auth
.claude/ vs ~/.claude/ layout Where config lives Config directory · Claude directory
Usage / limits (subscription) Budget sessions Claude Code + Pro/Max

References: Claude Code docs · Claude directory · Authentication · Ollama (optional local)

Todos

Pass when: Claude Code (Pro) hello works, you’ve skimmed the config tree, and you can explain session budget in one sentence.


Phase 1 — Agent loop

Topic Harness / “done” on On-Call Triage · Essay The Agent Said Done — and CI Is Red · Prior 0 · ~9–12 hr

Fix the routing bug only when npm test (your CI signal) is green — chat “done” is not merge-ready.

  agent says "done" ──▶ harness checks fake CI
                              │
              ┌───────────────┼───────────────┐
              ▼               ▼               ▼
           CI green        CI red         max steps
              │               │               │
           allow stop      keep looping    force stop

Without the CI gate, “done” is just another chat token.

Learn before you build

Knowledge Why Refresh
Phase 0 done Working Claude Code (Pro) path
Claude Code session + tools Brain already has a tool loop Claude Code overview · Hooks
Hooks in settings.json Enforce stop / observe outside chat Hooks · Settings
JSON / JSONL Fake CI / step logs
ReAct (high level) Loop shape ReAct paper (skim)
CI / PR gates Done ≠ merge GH Actions quickstart · essay Prerequisites

References: Claude Code hooks · Building effective agents · Essay

Todos

Pass when: agent may only claim done when CI is green — and you can explain why chat “done” ≠ merge (one sentence, no notes).


Phase 2 — Tools

Topic Tool surface · Essay Your Agent Has Too Many Tools · Prior 0–1 · ~6–7 hr

The model only sees schemas. A bloated catalog is a harness bug: access ≠ expertise.

  allowlist (5)          flood (20)
  ┌─────────────┐        ┌─────────────┐
  │ read_file   │        │ read_file   │
  │ write_file  │        │ write_file  │
  │ run_tests   │   vs   │ + 15 junk   │
  │ git_status  │        │   schemas   │
  │ search      │        │   (noise)   │
  └─────────────┘        └─────────────┘
       fewer steps            more tokens / thrash

Learn before you build

Knowledge Why Refresh
Phase 1 loop Tools plug into harness
Tool schema (name, description, JSON params) Model only sees schema Claude Code tools / MCP · Tool use concepts
Filesystem paths / cwd Coding tools
Prompt bloat / usage cost Too many tools hurts Pro/Max + Claude Code

References: Claude Code MCP · Anthropic tool use (concepts) · Essay

Todos

Pass when: you have a measured comparison and can explain why tool bloat is a harness problem.


Phase 3 — Skills & memory

Topic Rules that survive chat amnesia · Essays Forgot the Constraint · Monorepo Navigable to Agents · Prior 0–2 · ~6–8 hr

Durable rules live in CLAUDE.md / .claude/rules/ / skills — not in yesterday’s chat scrollback.

  cold session
       │
       ▼
  ┌────────────┐     ┌──────────────┐
  │ CLAUDE.md  │────▶│ On-Call Triage │
  │ + rules/   │     │   agent run  │
  │ + skills/  │     └──────┬───────┘
  └────────────┘            │
              stale memory (lies) ──▶ rules must win

Learn before you build

Knowledge Why Refresh
Phase 1–2 Rules constrain tools
CLAUDE.md · .claude/rules/ · skills Durable + on-demand guidance Memory · Skills · Directory · Rules vs hooks
Finite context Can’t paste whole repo Context windows
Monorepo layout Navigability Your day job

References: Config directory · Claude directory · Memory · Skills · Constraint essay · Monorepo essay

Todos

Pass when: cold start with only CLAUDE.md / rules / skills holds constraints — and you can explain in one sentence that rules are guidance (Phase 4 will enforce what rules cannot).


Phase 4 — Guardrails

Topic Trust boundaries · Essay Agent Trust Boundaries · Prior 0–2 (3 recommended) · ~6–9 hr

Side-effects need real approvals. Tool return values can lie — verify after write.

  tool call
     │
     ├─ read ──────────────▶ auto-allow (still log)
     ├─ write ─────────────▶ allow + verify-after
     └─ side-effect ───────▶ human “yes” required
                              (deploy, push, delete, …)

Learn before you build

Knowledge Why Refresh
Phase 2 allowlists Guardrails wrap tools
Least privilege Side-effect blast radius OWASP authz cheat sheet (skim)
Human-in-the-loop Approvals that matter Building effective agents
Verify-after-write Lying tools
settings.json permissions + hooks Enforced allow/deny — this is the guardrail, not CLAUDE.md Settings · Hooks · Rules vs hooks
Prompt injection / secrets Don’t leak keys Anthropic guardrails

References: Settings · Hooks · Strengthen guardrails · OWASP LLM Top 10 · Essay

Todos

Pass when: you can explain rules vs hooks vs guardrails with the On-Call Triage demo (rules-only fail under injection; hook/permission blocks deploy), and verify-after-write catches a lying tool.


Phase 5 — Planning

Topic Plan vs theater · Essay Planning Theater vs a Real Plan · Prior 0–1 (2 recommended) · ~4–11 hr

A plan is useful only if the harness updates it when blocked. A stale plan is theater.

  ReAct-only                    plan-then-act
  goal → act → act → …          goal → plan.md → act → update plan
                                      │                │
                                   (ignored?)      (live state)

Learn before you build

Knowledge Why Refresh
Phase 1 stop conditions Plan is loop state
ReAct vs plan-and-execute Two strategies ReAct · Effective agents
Good eng plan (AC, risks) Avoid theater Your design docs
(Opt.) Graphs LangGraph LangGraph concepts

References: LangGraph · Essay

Todos

Pass when: updating the plan once prevents a rewrite — and you can spot a stale plan.


Phase 6 — Subagents

Topic Orchestrator + workers · Essay Subagents That Argue · Prior 0–2 (5 recommended) · ~5–13 hr

Two agents can burn tokens arguing. Log dual cost and add a skip rule.

                 ┌──────────────┐
                 │ orchestrator │
                 └──────┬───────┘
            ┌───────────┼───────────┐
            ▼                       ▼
     ┌────────────┐          ┌────────────┐
     │ researcher │          │   coder    │
     └────────────┘          └────────────┘
            │                       │
            └──────────┬────────────┘
                       ▼
              cost(A) + cost(B)  →  skip rule?

Learn before you build

Knowledge Why Refresh
Phase 1–2 Multiple harnesses
.claude/agents/ Named subagents Claude can spawn Subagents · Directory
.claude/workflows/ · agent-memory/ Saved multi-step runs · per-subagent memory Directory
Orchestrator / worker Delegation Building effective agents
Dual token cost “Pay for both” Pricing
(Opt.) Chat bots OpenClaw OpenClaw channels

References: Config directory · Claude directory · Subagents · OpenClaw multi-agent · LangGraph multi-agent (opt.) · Essay

Todos

Pass when: you can show dual-cost numbers, a skip rule you’d ship, and point at .claude/agents/ (plus know workflows / agent-memory).


Phase 7 — Eval

Topic Ship bar · Essay “It Worked Once in Chat” Is Not a Ship Bar · Prior 0–2 (4 recommended) · ~6–13 hr

One lucky chat is a demo. A ship bar is a fixed suite with intentional fails.

  evals/cases.json ──▶ runner ──▶ pass/fail report
         │                           │
    ≥10 fixed cases            ≥1 intentional fail
         │                           │
         └──────────▶ PR gate metric ┘

Learn before you build

Knowledge Why Refresh
Headless Phase 1 harness Many automated runs
Test / CI mindset Pass/fail Your team’s CI
Golden fixtures Fixed cases Langfuse eval overview (skim)
Traces Debug runs Langfuse tracing

References: Langfuse docs · Essay

Todos

Pass when: report has ≥10 cases, ≥1 intentional fail, and a PR-gate metric you’d stand behind.


Phase 8 — Judgment & ops

Topic When agents make you slower · Essays Makes You Slower · Overnight PR Fantasy · Bot on PR · Prior 0–1, 4, 7 · ~6–10 hr

Overnight draft can be fine. Overnight merge is fantasy. Someone must own bot comments.

  night job
     │
     ▼
  draft PR / ticket ──▶ morning checklist ──▶ human merge?
     │
     ✗ auto-merge        (don’t)

Learn before you build

Knowledge Why Refresh
Phases 1, 4, 7 Judgment uses loop + safety + eval
Babysitting / opportunity cost Agents can slow you
Cron / n8n Overnight jobs crontab.guru · n8n docs
Draft PR ≠ merge Fantasy check GitHub PR flow
.worktreeinclude Copy gitignored files into Claude worktrees — not a second .gitignore Worktrees · gitignore vs worktreeinclude

References: n8n docs · Worktrees · Slower · Overnight · Bot ownership

Todos

Pass when: you can name tickets where the agent babysits you, who owns a bad bot comment, and explain .gitignore vs .worktreeinclude with the On-Call Triage .env.local demo.


Phase 9 — Context & RAG

Topic Wrong chunk, confident answer · Essay Wrong Chunk, Confident Answer · Prior 0–1 (3 recommended) · ~6–14 hr

Bad retrieval + high confidence is worse than “I don’t know.” Hooks set session context; RAG is optional.

  query ──▶ retrieve chunks ──▶ model answers
                  │
            wrong chunk
                  │
                  ▼
           confident wrong answer
                  │
                  ▼
           refuse / re-retrieve / cite

Learn before you build

Knowledge Why Refresh
Phase 1 system inject Hooks mutate context
Embeddings / vectors Retrieval HF embeddings chapter
Chunking tradeoffs Wrong chunk LangChain RAG tutorial · essay Prerequisites
Hallucination vs bad retrieval Diagnose confidence Reduce hallucinations

References: LangChain RAG · Open WebUI · Essay · Bot ownership (hooks in CI)

Todos

Pass when: you can demo wrong chunk → confident wrong → refuse / re-retrieve.


Phase 10 — Capstone (optional)

Topic Always-on team · Essay — (synthesis) · Prior 1–2, 4, 6–7 · ~7–17 hr

Optional. Convenience must not delete approvals (phase 4) or eval (phase 7).

Learn before you build

Knowledge Why Refresh
Phases 1–2, 4, 6–7 Capstone reuses them
Agent gateway / channels Always-on team OpenClaw docs
Claude as provider Auth + models Claude Code / Claude.ai account · OpenClaw Anthropic
(Opt.) Remote access Phone → gateway Tailscale KB

References: OpenClaw · Tailscale · Essays reading map below

Todos

Pass when: approvals and eval still exist — or you skip this phase because 1–9 already feel solid.


Phase 11 — Computer use & multimodal (optional)

Topic Browser / screenshot / voice as tools · Essay The Agent Clicked the Wrong Button · Prior 1–2, 4 · ~6–12 hr

DOM clicks and screenshots are a different tool class than read_file. Brittleness and page-borne injection dominate.

  goal ──▶ model ──▶ act on UI (click / type)
                │         │
                │         ▼
                │    screenshot / DOM
                │         │
                └──── observe ◀── page text can inject

The page is both sensor and attacker. Treat UI observations like untrusted tool returns.

Learn before you build

Knowledge Why Refresh
Phase 1–2, 4 Same loop + allowlist + approvals
Browser automation basics Computer-use tools Playwright intro (skim)
Prompt injection via content Pages/tickets lie Phase 4 injection todo · essay
Multimodal I/O Screenshot / voice as observation Essay

References: Anthropic computer use · Playwright · Essay

Todos

Pass when: you can demo UI thrash and page-injection refusal — or you skip this phase and stay on file/tools agents.


Workflow design (synthesis)

When you design an agent workflow for real work, stack these in order. Skip a layer and the failure mode from that phase shows up in prod.

Order Design question Harness owns Model proposes
1 What is “done”? SPEC / failing test / CI gate Code + “I’m finished” text
2 What can it touch? Tool allowlist, MCP deny rules Which tool to call
3 What must survive amnesia? CLAUDE.md, rules, skills (guidance) Chat reasoning
4 What needs a human? Guardrails: permissions + hooks + approval + verify-after-write Side-effect intent
5 How does it plan? Persist + update plan.md on block Plan content
6 When do you add agents? Skip rules, cost caps Delegation
7 How do you ship changes? Eval suite + PR gate metric One-off demos
8 Should this run overnight / in a worktree? Draft-only + checklist + owner; .worktreeinclude for gitignored config The diff

Anti-patterns (if you catch yourself doing these, re-read the matching phase):

  • Trusting chat “done” without observe → Phase 1
  • Connecting every MCP server “just in case” → Phase 2
  • Pasting constraints into chat instead of files → Phase 3
  • “Please be careful” with no hook/permission for deploy (rules-only) → Phase 4
  • Plan written once and never updated → Phase 5
  • Researcher + coder on every ticket → Phase 6
  • “Worked in my session” as ship bar → Phase 7
  • Auto-merge because CI was green once → Phase 8
  • Expecting .env.local in a worktree with only .gitignore → Phase 8 (.worktreeinclude)

Essays (reading map)

Open after the matching lab, not before.

Phase Essay
1 The Agent Said Done — and CI Is Red · Spec Before the Agent Writes
2 Your Agent Has Too Many Tools (MCP + economics)
3 Forgot the Constraint · Monorepo Navigable to Agents
4 Agent Trust Boundaries (injection)
5 Planning Theater vs a Real Plan
6 Subagents That Argue
7 Eval Is Not a Demo (audit) · Spec essay
8 Makes You Slower · Overnight PR Fantasy (durable) · Bot on PR
9 Wrong Chunk, Confident Answer
10 On-Device Without the Mini Fantasy
11 The Agent Clicked the Wrong Button

Finish line

You’re done with the core lab (Phases 0–7, ideally 8) when you can:

  • Draw the harness loop and label what you own vs what the model owns.
  • Walk the workflow design table and give a real example for each row from your lab.
  • Check understanding: explain each linked essay’s claim, failure mode, and fix — demo optional for 9–11.
  • Defend: tool surface, guardrails, eval bar, spec-before-code, and when not to use an agent.
  • On-Call Triage (demo-on-call-triage): one tiny site repo with harness, tests, deploy gate, and .claude/ config you’d recognize at work.
  • Directory literacy: open the official explorer or your Config directory table and account for every Project node in ~/demo-on-call-triage.

Design review test: A peer asks “should we agentify this ticket?” — you can answer with: done signal, tool surface, approval gates, eval coverage, and babysitting cost. If you can’t, you’re not done yet.

Config spot-check (60 seconds): Without looking — (1) rules vs hooks vs guardrails in one sentence each? (2) where do hooks live? (3) .gitignore vs .worktreeinclude? (4) where does team MCP config live? If vague, open Phase 4 / Phase 8 How and expand the notes, plus Config directory.

Not a goal: matching Claude with a local 70B or building a product — this lab is harness literacy.