πŸ—ƒοΈResources7
πŸ› οΈ

Agentic Engineering

The engineer’s job shifts from writing code to building the system that checks it. Agents are allowed to do more only as fast as the codebase can prove their work is right β€” so the investment goes into verification, maps, guardrails and evals, and autonomy follows. These are guidelines for any project, language or agent harness; file paths are suggested conventions, not requirements.

4 trust rungs5 practicestalk β†—

πŸͺœThe trust ladder

Autonomy is earned one rung at a time. Early on you watch every action; at the top, a label on an issue starts work nobody prompted. Move up only after the rung below has been boring for a while β€” and write down which rung the project is on, so nobody hands an agent more trust than the guardrails can back.

RungAgent mayHuman doesUnlocked by
1 Β· In the loopEdit in an isolated worktree and run the verify gateReads every diff, watches every actionA single command that proves a change works
2 Β· PR per issueOpen one PR per issue or phase, with a pasted verification reportReviews and mergesFeature map, guardrails in CI, a PR template that asks how
3 Β· Auto-mergeMerge its own PR when every required check passesReads merged PRs, watches the evalsEvals that stay green several runs in a row
4 Β· Hosted triggersStart work from an issue label β€” triage, implement, answer @mentionsLabels issues; reads the agent's reportA skill per job and a workflow that runs it in the cloud

🧰The practices

Each one is a rule, the everyday version of it, and the concrete done state β€” what you would find in a repository where the rule is enforced rather than hoped for.

1

πŸ” Verification loops

06:05 β†—

An agent is not done when the code compiles; it is done when it has run the thing and shown you the output.

πŸ§’ Explain like I’m five

Before you say you cleaned your room, you open the door and look. You don't just say you did it.

Agents hallucinate β€” they will confidently report a fix that was never exercised. The single highest-leverage investment is giving them a way to check their own work: run the app, drive the UI, read the logs, render the output. Trust scales with the verification layer, not with the model.

βœ“ Do this

One command runs everything CI runs β€” typecheck, lint, format check, tests, build. A verify skill tells the agent to run it and paste the real output, and to say which step could not run instead of skipping it quietly. Add scripts that exercise the app without a human: render a fixture, replay a request, drive a browser.

a single verify command.claude/skills/verify/SKILL.mdfixture / replay scriptsbrowser automation
2

πŸ—ΊοΈ Feature map

10:17 β†—

Write down every user-facing surface with where it lives and the exact command that reproduces it.

πŸ§’ Explain like I’m five

A treasure map with an X on every room, so a new kid can find the kitchen without opening every door.

A vague report β€” β€œthe dialog that lists times is wrong” β€” makes an agent flail through the codebase. A table mapping each surface to its entry point, renderer, data and reproduce command turns that report into a lookup. CI keeps it honest: a surface that is not on the map fails the build.

βœ“ Do this

A table with one row per route, command, screen or endpoint: its id, the file that handles it, the file that renders it, the data it touches, and a copy-pasteable command or selector that reaches it. A CI script fails when a surface id in code is missing from the table.

docs/FEATURE_MAP.mdsurface ids as named constantsa map-coverage check in CI
3

🚧 Hard guardrails, not advice

37:58 β†—

If you leave the same review comment twice, turn it into a lint rule or a CI check.

πŸ§’ Explain like I’m five

Instead of reminding your brother not to touch the stove every day, you put a gate in front of it.

Instructions in a prompt are suggestions; a failing build is not. Ban whole patterns mechanically β€” a risky API, cross-layer imports, secrets in client code. The agent does not have to remember the rule, because the rule will not let it through.

βœ“ Do this

Layer boundaries enforced by import-restriction lint rules, not by a paragraph in the agent guide. Server-only modules that fail the build if pulled into client code. Migrations checked against the schema and applied from empty in CI. The package manager pinned so the wrong one refuses to install. A table in the docs that maps each rule to what enforces it.

lint import restrictionsserver-only guardsrequired CI checksrule β†’ enforcer table
4

πŸ“¦ Colocate by feature

42:55 β†—

Put everything one feature needs β€” handler, renderer, parser, tests β€” in one directory.

πŸ§’ Explain like I’m five

Each board game keeps its own pieces in its own box, so you never have to dig through a giant pile.

An agent scoped to one directory makes small, reviewable changes and cannot accidentally reach into another feature. Organizing by type (all handlers here, all views there) forces every change to touch the whole tree, which is exactly the kind of diff you cannot trust.

βœ“ Do this

features/<name>/ holds that feature's entry point, rendering, input parsing and tests. Pure domain logic sits in its own layer with no I/O. A skill spells out the steps for adding a new surface so it lands in the right places the first time.

features/<name>/a pure domain layer.claude/skills/add-<surface>/SKILL.md
5

πŸ§ͺ Evals for the instructions

18:39 β†—

Agent instructions are code: test them with fixed scenarios and hill-climb until they pass reliably.

πŸ§’ Explain like I’m five

When you teach someone a card game, you play a few practice rounds to check they really got the rules.

Changing a sentence in the agent guide can silently change behavior. An eval playbook is a set of prompts with pass criteria, run in fresh sessions and scored. A scenario that needed a nudge is an instruction bug β€” fix the sentence, and add a guardrail if the mistake was mechanical.

βœ“ Do this

A table of scenarios β€” including ones the agent should refuse, like putting I/O in the domain layer β€” each with pass criteria. Score 2 (passed alone), 1 (passed after one nudge), 0 (failed). Log runs as dated, append-only notes, and change skills only through PRs.

docs/EVALS.mddated eval logsAGENTS.md.claude/skills/

πŸ—οΈBuilding a whole project autonomously

Given a written plan and the practices above, one prompt β€” β€œbuild this whole project, creating issues and docs as needed” β€” is enough to start. This is the loop the agent should run, and because every step leaves an issue, a branch, a PR or a doc behind, the work can be audited without the transcript.

  1. 1

    Plan β†’ issues

    Start from a written plan and split it into phases. Each phase becomes a milestone; each unit of work an issue with acceptance checkboxes. Anything that needs secrets, billing or an admin gets a needs-human label instead of being faked.

  2. 2

    Guardrails first

    Phase 0 is not a feature: it is the CI gate, the lint boundaries, the feature map, AGENTS.md and the skills. Everything after runs inside them.

  3. 3

    One worktree per unit of work

    Each phase or issue gets its own branch and git worktree, so parallel agents never share a working tree. Agents never push to the default branch.

  4. 4

    Locate β†’ reproduce β†’ change

    Find the surface on the feature map, write the failing test next to the feature, then change code inside the boundaries.

  5. 5

    Verify, then document

    Run the verify skill and keep the real output. Changed behavior means a changed living doc in docs/; a new surface means a new feature-map row.

  6. 6

    Ship as a PR

    One PR per issue that says Closes #N and pastes how it was verified. Required checks are the gate. Optionally mirror docs/ to a wiki with a workflow so the docs stay link-checked in one place.

πŸ•A hosted trigger: the Benny-style triage agent

In the talk, β€œBenny” is an agent that picks up a bug report, reproduces it in a cloud environment, and says whether the default branch already fixes it β€” before an engineer has read the report. The shift is that work starts from an issue, not from a human typing a prompt: rung 4 of the ladder.

TriggerJobWhat happens
Label an issue triageTriage issueRuns the triage skill: reproduce with a failing test, comment with the result
Label an issue agentImplement issueImplements on issue-N-agent, runs verify, opens one PR that Closes #N
Comment @claude …Answer mentionAnswers in place on the issue or PR

Making one

  1. 1.

    Write the skill before the trigger

    agent can do

    .claude/skills/triage-bug/SKILL.md must already work when you run it by hand from a local session. A hosted trigger only removes the human who typed the prompt; it cannot rescue a skill that flails locally.

  2. 2.

    Add the workflow

    agent can do

    One job per label. Pin actions by SHA, give each job only the permissions it needs, and set a concurrency group per issue so re-labeling does not start two agents on the same bug.

  3. 3.

    Add the API key secret

    needs-human

    ANTHROPIC_API_KEY under Settings β†’ Secrets and variables β†’ Actions. An agent cannot do this for itself, so track it as a needs-human issue.

  4. 4.

    Install the Claude GitHub App

    needs-human

    claude /install-github-app from a local checkout. This matters more than it looks: commits pushed with the default GITHUB_TOKEN do not trigger other workflows, so an agent PR would sit forever without its required checks.

  5. 5.

    Smoke test

    needs-human

    Label a real issue triage and confirm that within minutes a comment arrives naming the feature-map row and a reproduction result.

.claude/skills/triage-bug/SKILL.md (abridged)
---
name: triage-bug
description: Triage a bug report β€” locate the surface in the feature map,
  reproduce in a fresh worktree, check whether the default branch already
  fixes it, and leave a precise comment or a fix PR.
---

1. Locate. Map the report's words to a row in docs/FEATURE_MAP.md.
2. Fresh worktree from the default branch.
3. Reproduce with the row's command. Write the failing test next to
   the feature. If it passes, say "cannot reproduce at <sha>" with
   the exact steps and stop.
4. Bisect only if the report names a version that worked.
5. Small and inside the boundaries β†’ fix, verify, PR that Closes #N.
   Otherwise comment: surface, reproduction, test path, file:line.
6. Never weaken a check to make the reproduction pass.
.github/workflows/agents.yml β€” the triage job
name: Agents

on:
  issues:
    types: [labeled]

jobs:
  triage:
    name: Triage issue
    if: github.event.label.name == 'triage'
    runs-on: ubuntu-latest
    permissions:
      contents: read        # write only if it may push a fix branch
      issues: write
      pull-requests: write
      id-token: write       # claude-code-action's GitHub App exchange
    concurrency:
      group: triage-${{ github.event.issue.number }}
    steps:
      - uses: actions/checkout@v5   # pin by SHA in practice
        with:
          fetch-depth: 0            # the skill may need git bisect
      - run: ./scripts/setup        # install your toolchain + deps
      - uses: anthropics/claude-code-action@v1
        with:
          anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
          track_progress: true
          prompt: |
            Use the triage-bug skill on issue #${{ github.event.issue.number }}.
            Locate the surface in docs/FEATURE_MAP.md, reproduce on the default
            branch with a failing test next to the feature, and finish with ONE
            comment: feature-map row, reproduce command, test path + output,
            suspected file:line, and "confirmed on <sha>" or
            "cannot reproduce on <sha>". Never weaken a check.
          claude_args: |
            --max-turns 80
            --allowedTools "Bash(git *),Bash(gh *),Read,Grep,Glob,Edit,Write"

The permissions trade-off. A triage agent with contents: read can only comment; it cannot push anything. Letting the same skill open a small fix PR needs contents: write. Pick one per job: comment-only triage with read, and let the separate agent label carry the write permission, so the blast radius of a mislabeled issue stays at β€œa wrong comment”.

πŸ“šSources

Where each idea on this page comes from.