nextv2.0.0
Run the server

Logs and disk space

Where Kraft writes its logs, how to read a session's log, and how to free the disk space worktrees use.

You will find the log you need, read what an agent printed with kraft view logs, and free the disk space that worktrees take.

Before you start

  • $KRAFT_HOME is ~/.kraft unless you set it; see Environment variables. The commands find run/ as Kraft does: $KRAFT_RUN_DIR when you set it, else run/ under $KRAFT_HOME.
  • Deleting old session logs needs the server stopped. If Kraft runs as a service, stop it as Stop a service says.

Find the logs

All logs are in run/logs/:

  • server.log is the server's own output: startup, shutdown and its reason, errors. A foreground kraft writes here as well as to the terminal. Kraft moves it to server.log.1 at start once it passes about 8 MB, replacing the last one.
  • <session id>.log is one worker session: everything an agent or command printed. Kraft never deletes these.
  • <session id>.times.jsonl holds when each line of that session's log was written, one JSON object per line: {"n": <line number>, "t": <timestamp>}. kraft view logs and the item page's log take a line's time from it when the line carries none of its own.

Read a session's log through Kraft rather than by file name:

CommandWhat it shows
kraft view logs IDThe newest session. While the item is stopped, the one that stopped it.
kraft view logs ID --session SESSIONOne session.
kraft view logs ID -fA running session, followed.

A session's log is its output with stdout and stderr merged. Each line shows a time, a source and the text. The time is when Kraft saw the line, in UTC. It is --:--:-- for a session Kraft took over after a restart, and for a log from before Kraft recorded times.

The source is stdout for a plain line. A line of the agent's structured log is agent (what the agent says), tool (a tool call or its result) or sys (the session's own start and result lines):

09:30:15 sys    init claude-sonnet-5-5
09:30:17 agent  I'll start with the failing test.
09:30:18 tool   Read(tests/test_board.py)
09:30:21 stdout npm warn deprecated inflight@1.0.6

While the item is stopped, a bare kraft view logs ID shows the session that stopped it, and names the newest one, such as an auto-escalation, on stderr. With -f it follows the newest one instead, and names on stderr the session that stopped the item.

To list an item's session ids:

kraft view events ID --type worker_session_created --json

You know it worked when kraft view logs ID prints the lines the agent or command wrote. For the server's own log, read the end of run/logs/server.log.

Limit the disk worktrees use

Without a limit, worktrees use disk until you notice. Set one in policy.yaml and Kraft tells you before the disk is full, and holds new starts at the limit:

config/policy.yaml
storage:
  worktrees:
    limit: 10G
    quota: 8G   # optional; defaults to 80% of limit

Run kraft admin reload to apply it, or edit Settings › Policy › Housekeeping › Storage. A size is a whole number and a unit: 1000M, 10G, 1T. A bare 10 is refused. See policy.yaml.

StateWhenWhat Kraft does
okUsage is at or under quota.Nothing.
over_quotaUsage is over quota, at or under limit.Warns in kraft admin doctor and kraft admin health.
heldUsage is over limit.Queues starts that need a new worktree, and the instance reads degraded.

The figure is the disk the worktrees and sandbox stores take, measured every 10 minutes and at startup. Kraft deletes nothing for the limit on its own unless you turn on automatic clean-up.

See where you stand:

kraft admin doctor
kraft admin health

Over the limit, make room in any of these ways, then wait about 10 seconds for the queue to start what is held:

  • Archive finished items, from Settings › Storage or the board's Done group. Archiving removes the worktree and any uncommitted changes in it, keeps a branch with unpushed commits, and leaves the item restorable under Archived.
  • Finish or abandon live work.
  • Raise limit.

A start that is held shows as queued with work_item_storage_held on its timeline. An item that already has its worktree is never held, so finishing it is always possible.

You know it worked when kraft admin doctor reports the storage line as ok, and a held item leaves queued.

Let Kraft make room

An instance left running unattended can sit held with nobody to clean up. Add auto_cleanup and Kraft archives finished items itself when worktrees pass the limit:

config/policy.yaml
storage:
  worktrees:
    limit: 10G
    auto_cleanup:
      min_age: 24h   # the default; the block being there is what turns it on

Over limit, Kraft archives completed and abandoned items, oldest first, until usage is at or under quota. It never takes an item that ended less than min_age ago, a number of hours or days (12h, 24h, 2d). The floor is there because an item that just ended, or a cancelled one you kept to salvage, may hold uncommitted work, and archiving removes it. A branch with unpushed commits is kept. auto_cleanup needs a limit.

If every finished item is newer than min_age, nothing is archived and starts stay held. kraft admin doctor then says how many finished items were too recent, and you make room as above.

You know it ran when an item's timeline has work_item_archived with reason: storage, and the Archived view shows it as archived by auto.

Clean up from the Storage page

Settings › Storage shows what each worktree uses and archives the finished ones for you. Use it when worktrees are over the limit, or when you want the space back.

  1. Open Settings › Storage. The bar shows the figure against the quota and the limit. Refresh measures again; the figure on the page is the last measurement, with its age beside the title.
  2. Tick the rows you want to free. Only completed and abandoned items that are not archived have a box. Clean up all reclaimable takes every one of them.
  3. Press Clean up selected or Clean up all reclaimable, and read the confirmation. It lists what is freed, where usage lands against the quota and limit, and per item the uncommitted files that will be lost and whether the branch stays.
  4. Press Archive N items.

Each item moves to Archived. Its worktree and any uncommitted changes in it are gone, a branch with commits nothing else holds is kept, and you can restore the item from Archived as a record without its worktree. Held starts go within seconds of the clean-up.

You know it worked when the bar drops below the limit and the archived rows leave the list.

From a shell, kraft view storage prints the same breakdown and kraft item archive --reclaimable archives after showing the same confirmation. See View verbs.

Reclaim disk space

Each work item gets a git worktree in run/worktrees/<item id>/, a full checkout of its repo, plus any dependencies its setup command installed. That adds up.

  1. See what uses space:
    run="${KRAFT_RUN_DIR:-${KRAFT_HOME:-$HOME/.kraft}/run}"
    du -sh "$run"/*
    

    With storage.worktrees.limit set, kraft view storage lists the worktrees item by item instead. kraft item archive --reclaimable archives every finished one, after showing what each loses.
  2. Remove the worktrees you no longer need. A worktree is removed when its item is abandoned or archived:
    • Abandon a work item you no longer want: kraft item abandon ID --yes. It removes the worktree, and deletes the item's local branch and its attachment copies in run/attachments/. Uncommitted work is lost, and so are commits you never pushed.
    • Archive a completed or abandoned item from the board's Done group, with kraft item archive ID (it previews first and needs --yes), or with POST /api/work-items/ID/archive. It removes the worktree and keeps the item's record and its attachment copies, so you can still duplicate it. Commit uncommitted changes in the worktree first, or copy them out from kraft repo open ID: archiving loses them.
    • Auto-archive. archive.after_days in policy.yaml archives completed and abandoned items that old. The shipped file sets 30. Lower it to reclaim space sooner. See policy.yaml.
  3. Delete old session logs in run/logs/ and result files in run/results/ by hand, with the server stopped. They stay after archiving.

You know it worked when du -sh "$run"/* shows worktrees smaller, and ls "$run/worktrees" no longer lists the item.

What archive does to the branch

  • It deletes the local branch only when every commit on it is somewhere else too: another branch such as the base, a remote-tracking branch, a tag, or what Kraft pushed. Otherwise the branch stays, and the archive event says how many commits it kept.
  • Commits on a detached HEAD in the worktree are kept on a new branch, kraft/rescued/<item id>. If Kraft cannot make that branch, it archives the item but leaves the worktree, and the archive event's worktree_kept says why.

kraft item complete and kraft item cancel keep the worktree until the item is archived. A cancelled item that never pushed keeps its branch after that too. Delete it by hand once you are done with it: git branch -D <branch>.

Next steps

Copyright © 2026