Handmade Claude Code 3/7 — Context and Sessions

Part three of the Handmade Claude Code campaign: the agent learns where it is and remembers what happened. A loop with tools is a capable stranger; what makes it a colleague is context — the project's own instructions, the files the user points at, the environment it runs in — and memory: a conversation that can be picked up again, and one that survives running out of room.

This session continues the agent you built in parts one and two, in the same repository. Nothing about how it is started changes; what changes is what it knows before the first model call, and what it keeps after the last.

The command and the protocol, unchanged

agent: <command>     started as:  <command> -C <dir> [--yes] -p "<prompt>"

Project instructions

Before the first model call, the agent walks from the working directory up to the filesystem root and collects, in every directory, the file AGENTS.md — or CLAUDE.md when there is no AGENTS.md beside it. Their contents go into the system prompt, outermost directory first, innermost last.

Inside such a file a line that is exactly @<path> imports another file: its contents are inlined in place, the path relative to the importing file. Imports nest (at least two levels deep); a file already imported is not imported twice.

Mentions

A token @<path> in the prompt attaches that file: the user message carries the prompt as typed and the file's contents (a second text block, or the same block — your call). A path that does not exist is left as typed.

Where and when

The system prompt says where and when the agent is: the absolute path of the working directory, today's date as YYYY-MM-DD, and — when the working directory is inside a git repository — the current branch name.

Sessions

Every headless run is a session, named by the session_id the JSON output carries. Where and how you store it is yours (a file per session is the usual answer); what it must allow is:

  • --resume <session_id> -p "<prompt>" — the new prompt is appended to that session's conversation and the whole of it goes to the model.
  • --continue -p "<prompt>" — the same, with the most recent session of this working directory.

Compaction

Contexts fill up. .agent/settings.json may set a budget:

{"compaction": {"input_tokens": 100000}}

When the input_tokens the last reply reported exceeds the budget, the next model call is not the next turn — it is a compaction call: the conversation so far plus one user message asking the model to summarise it. The reply's text becomes the new conversation — one user message carrying the summary (worded however you like) — and only then does the turn the user asked for go to the model, on top of the summary. The old messages are gone from every request after that. The default budget is yours; the checks set a small one.

The judges

The quality panel — architecture, performance, code quality, test quality, technical governance and DX review — sits on the rungs where its subject is decided, one verdict per judge per rung, on top of the rung's own points. There is no closing review: what you build is judged as you build it, and a rung you never reach is a verdict you never get.

The ladder

  • Set up and carry parts one and two forward (10)
  • AGENTS.md is the system prompt (20)
  • Up the tree (20)
  • Imports (20)
  • Mentions (20)
  • Where and when (10)
  • Resume a session (30)
  • Continue the last session (20)
  • Compaction (40)
Sessions

0

Visibility

Public

Category

Reinvent the Wheel

Slug

handmade-claude-code-3-context

Duration

25 min

Judge reviews

~13 per session

Active session

No

Points

10–40

Tags
  • ai-agent
  • harness
  • context
  • handmade-claude-code
  • campaign
  • 1

    Set up and carry parts one and two forward

    10

    pts / check

    +10 pts per passing check · +10 for completing the task

    This part continues your agent. Same repository, same command, same
    model protocol, same six tools — what grows is what the agent knows
    before the first model call and keeps after the last.

    agent: started as: -C

    [--yes] -p ""

    Your AGENTS.md (or README.md) must still carry the two lines the
    platform captures into session memory: agent: and test:. If you are
    starting in an empty folder, your earlier work is fetched for you —
    check that the lines are there and that the agent still builds and
    runs.

    The first rung re-checks what parts one and two earned: a read tool
    call through the scripted model. Everything after it is context work —
    AGENTS.md up the tree, imports, mentions, the environment, sessions and
    compaction.

    Wrapping claude, codex, gemini, aider or any other coding agent,
    or building on an agent SDK that owns the loop, is not building one.

    Judged by
  • 2

    AGENTS.md is the system prompt

    20

    pts / check

    +20 pts per passing check · +10 for completing the task

    The project speaks first. An AGENTS.md in the working directory is
    read before the first model call and its contents go into the system
    prompt — the rules of the house, ahead of anything the user types.

    The check writes an AGENTS.md with a marker and looks for the marker in
    the first request.

    Judged by
  • 3

    Up the tree

    20

    pts / check

    +20 pts per passing check · +10 for completing the task

    Instructions live at every level. From the working directory up to the
    filesystem root, every directory may carry an AGENTS.md — or a
    CLAUDE.md when there is no AGENTS.md beside it — and all of them go
    into the system prompt, outermost first, innermost last.

    In one directory AGENTS.md wins: a CLAUDE.md next to it is ignored.

    Judged by
  • 4

    Imports

    20

    pts / check

    +20 pts per passing check · +10 for completing the task

    An instructions file may pull in another. A line that is exactly
    @<path> inside AGENTS.md (or CLAUDE.md) inlines that file where the
    line stands, the path relative to the importing file. Imports nest —
    the check goes two levels deep — and a file already imported is not
    imported twice.

    Judged by
  • 5

    Mentions

    20

    pts / check

    +20 pts per passing check · +10 for completing the task

    The user points, the agent attaches. A token @<path> in the prompt
    means: send the prompt as typed, and send that file's contents with it
    — in the same user message, as a second text block or inside the first.
    A path that does not exist stays as typed and attaches nothing.

    Judged by
  • 6

    Where and when

    10

    pts / check

    +10 pts per passing check · +10 for completing the task

    The model should not have to ask. The system prompt says the absolute
    path of the working directory, today's date as YYYY-MM-DD, and — when
    the working directory is inside a git repository — the current branch
    name.

  • 7

    Resume a session

    30

    pts / check

    +30 pts per passing check · +10 for completing the task

    A conversation can be picked up. The JSON output of a run names its
    session; --resume <session_id> -p "<prompt>" appends the new prompt to
    that conversation and sends all of it — the earlier prompt, the earlier
    answer as an assistant message, then the new prompt, in that order.

    Where sessions are stored is yours; that they can be found is not.

  • 8

    Continue the last session

    20

    pts / check

    +20 pts per passing check · +10 for completing the task

    --continue is --resume without the id: it picks the most recent
    session of this working directory. Two separate runs, then a third with
    --continue: the third sees the second and not the first.

  • 9

    Compaction

    40

    pts / check

    +40 pts per passing check · +10 for completing the task

    When the context runs out, the agent makes room. With a budget in
    .agent/settings.json{"compaction": {"input_tokens": 5000}} — a
    reply that reports more input_tokens than that means the next model
    call is a compaction: the conversation so far plus a request to summarise
    it. The summary the model returns becomes the whole conversation (one
    user message), and only then does the pending turn go to the model, on
    top of it. The old messages never travel again.

    The check: run one makes a tool call, then answers while reporting a huge
    context. Run two resumes it. Call three must be the compaction (it sees
    the old markers); call four must carry the summary and the new prompt and
    none of the old markers.