Logs and disk space
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_HOMEis~/.kraftunless you set it; see Environment variables. The commands findrun/as Kraft does:$KRAFT_RUN_DIRwhen you set it, elserun/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.logis the server's own output: startup, shutdown and its reason, errors. A foregroundkraftwrites here as well as to the terminal. Kraft moves it toserver.log.1at start once it passes about 8 MB, replacing the last one.<session id>.logis one worker session: everything an agent or command printed. Kraft never deletes these.<session id>.times.jsonlholds when each line of that session's log was written, one JSON object per line:{"n": <line number>, "t": <timestamp>}.kraft view logsand 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:
| Command | What it shows |
|---|---|
kraft view logs ID | The newest session. While the item is stopped, the one that stopped it. |
kraft view logs ID --session SESSION | One session. |
kraft view logs ID -f | A 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:
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.
| State | When | What Kraft does |
|---|---|---|
ok | Usage is at or under quota. | Nothing. |
over_quota | Usage is over quota, at or under limit. | Warns in kraft admin doctor and kraft admin health. |
held | Usage 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:
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.
- 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.
- 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.
- 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.
- 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.
- See what uses space:
run="${KRAFT_RUN_DIR:-${KRAFT_HOME:-$HOME/.kraft}/run}" du -sh "$run"/*
Withstorage.worktrees.limitset,kraft view storagelists the worktrees item by item instead.kraft item archive --reclaimablearchives every finished one, after showing what each loses. - 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 inrun/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 withPOST /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 fromkraft repo open ID: archiving loses them. - Auto-archive.
archive.after_daysinpolicy.yamlarchives completed and abandoned items that old. The shipped file sets30. Lower it to reclaim space sooner. See policy.yaml.
- Abandon a work item you no longer want:
- Delete old session logs in
run/logs/and result files inrun/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'sworktree_keptsays 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
- Templates and Settings: the Storage screen in full
- Back up and restore the database: copy the database before you delete anything by hand
- policy.yaml: set
storage.worktrees,archive.after_daysand the rest ofpolicy.yaml - View verbs: every flag of
kraft view logs
Back up and restore the database
Back up Kraft's database while the server runs, check the backup, restore it, and find the copy Kraft makes before an upgrade.
Run Kraft as a service
Start Kraft at login and restart it if it exits, set its environment, stop or remove the service, and run a second instance beside the first.