nextv2.0.0
Security and project

Source map

Which module under src/kraft/ holds what, and where to go to change a given thing.

This page is for contributors. It lists what each part of src/kraft/ holds, and where to make each kind of change. For how those parts fit together, see Architecture.

Module map

Every path below is under src/kraft/.

Serving

PathWhat it does
cli/The kraft command: item, view, repo and admin verb groups, and starting the server. cli/verify.py is kraft repo connect --verify.
client/The one HTTP client. transport.py is the wire, actions.py changes things, reads.py reads, context.py knows which item a worker stands in.
mcp.pykraft admin mcp: the MCP tools, each a call into client/.
api/__init__.pyBuilds the FastAPI app, installs middleware, serves the SPA.
api/startup.pyThe lifespan: opens the database, reattaches sessions, starts the pollers.
api/deps.pyHelpers shared by routes, including spawn, which starts a walk.
api/perimeter.pyWho may call the API at all.
api/apidocs.pyThe /docs and /redoc pages, with their scripts pinned to one release and checked by hash.
api/routes/One module per resource: work_items, lifecycle, gates, review, board, artifacts, sessions, repos, settings, harnesses, search, auth, check, admin, drafts.
api/routes/lifecycle.pyPause, resume, retry, skip, abandon, complete, cancel, escalate.
api/routes/sessions.pyLogs, permission requests, the WebSocket.
api/routes/admin.pyPending changes, restart, update.
api/routes/drafts.pyThe Templates editor's unpublished edits.
api/config_check.pyChecks a config file the way saving it would.
drafts/, apply.pyUnpublished config and item-chain edits kept server-side, and what is saved but not yet running (reload and restart items).
ws.pyFans committed events out to WebSocket clients.
render.pyTerminal formatting for the CLI.

Running a chain

PathWhat it does
executor/entry.pyIntake, attachments, and closing an item's issues in beads when it completes.
executor/walk.pyThe walk: node by node, with recovery, the fix loop, escalation and every stop.
executor/dispatch.pyRuns a node's steps and tasks, measures the result, collects findings, and asks the fix-loop judge.
executor/gates.pyOpening gates, approval and rejection, agent gate review, and automatic escalation of stuck stops.
executor/stops.pyWrites each kind of stop, and guards every claim so an active item always has a walk behind it.
executor/resuming.pyResuming after a restart, and addressing a steer to paused tasks.
executor/retry.py, store/forks.py, templates/forks.pyA retry forks the run at a task, step or node path.
executor/prompts.pyThe text Kraft adds to an agent's prompt: steers, failures, findings, review threads, progress.
executor/context.pyWalk results and the Steer object.
executor/fallback.pyMoving a rate-limited or unavailable agent task to its next fallback: entry.
executor/read_only.pyChecks that a read_only step changed nothing.
builtins.pyWork Kraft does itself: the worktree, setup, rebases, changed-test scopes.
waits.pyExternal waits and the scheduler that re-enters them.
rate_limit_retry.pyRe-enters a rate_limited item after its reset.
mr_poller.pyNotices a merge request closed on the forge without merging.
caps.py, cap_levels.pyTime caps per scope, and the poller that stops parked items.
policy.pyLoads policy.yaml: loops, caps, budget, concurrency, escalation settings.
findings.pyThe finding schema reviewers report, and its identity across rounds.
escalate.pyEscalation turns: the agent a stopped item hands to.
auto_escalate_delay.pyFires a delayed automatic escalation.
gate_review.pyAn agent reviewing a gate before a person sees it.
review.pyThe one producer of "what changed" for the gate viewer and review agents.
review_reply.pyThe agent that answers review threads.
node_runs.pyPins the commit each node run started and ended on.
progress.pyReads a plan's ## Task N headings for "Task 3 of 6".

Templates

PathWhat it does
templates/models.pyThe typed chain schema: tasks, steps, nodes, chains, canonical paths.
templates/library.pyLoads library.yaml and chains/ from the config directory and resolves extends.
templates/environment.pyWorkspaces, areas, targets and harness profiles a chain runs against.
templates/revision.pyPlan-driven chain revision.
templates/retry.pyPolicy-bounded overrides a retry may carry.
templates/catalogue.py, templates/positions.pyThe library as a list for the UI, and YAML positions for editor errors.
overrides.pyValidates per-item model and per-node overrides.
skill.py, skills/The method an agent follows (spec, plan, code review, and so on), injected through its system prompt.

Add-ons

PathWhat it does
addons/manifest.pyThe models for collection.json and addon.json, and the fixed layout of an add-on's files.
addons/config.pyThe models for addons.yaml and addons.lock.
addons/fetch.pyFetches a collection into a bare mirror, extracts one add-on under the size and content limits, computes the digest and writes the store.
addons/review.pyWhat an install or update would change, split into reach and content.
addons/update.pyInstalls and updates: check, lint, review, accept, write. Also the update lock and auto-update.
addons/load.pyThe installed add-ons as the library and the agent-profile table read them, the load-time checks, restoring a missing store and collecting unused ones.
cli/addon.pyThe kraft admin addon verbs.

Agents and workers

PathWhat it does
harness.py, harnesses/*.yamlA harness: how to launch one agent CLI, described as data.
adapters/agent.py, adapters/profiles.pyResolve an agent task to a harness profile and an agent profile, and build its command line and context.
adapters/subprocess.pyLaunch a session, watch its log, read its result file, settle its status.
adapters/artifact_notes.pyWhat each document kind is for, in the prompt.
adapters/hook_install.py, permission_hooks.py, permission_rules.py, grants.py, registration.pyThe permission gate across harnesses: hook install, tool policy written into each CLI's config, named grants, and the permission tool's name.
usage.py, logs.pyToken, cost and time per session, and reading a session's log.
worker/env.py, worker/steering.pyA worker's environment, and the standards injected into its prompt.
worker/reattach.pyAdopting sessions that survived a restart.
worker/worktree_read.pyReading a file an agent wrote, safely.
worker/backends/, worker/sandbox.pySandboxed sessions in Docker or Podman, and host git hardening.
worker/egress.py, worker/channel.py, worker/ca.py, worker/inject.py, worker/callback.pyThe egress proxy for sandboxed sessions: per-session channels, its CA, injected credentials, and what a worker's callbacks may reach.
worker/refstore.pyA sandboxed worker's private ref store.
worker/kit.pyReads one Docker Sandbox Kit you wrote and lowers it onto the docker backend's policy.
worker/session_mcp.py, worker/shim.py, worker/bin/kraftThe MCP server and kraft shim a sandboxed worker calls back through.

Forge and trackers

PathWhat it does
adapters/forge/run.pyPicks the backend and runs a forge node against one or several repos.
adapters/forge/gh.py, adapters/forge/glab.pyGitHub through gh, GitLab through glab.
adapters/forge/git.py, adapters/forge/mr.py, adapters/forge/ci.py, adapters/forge/models.pyLocal git, the merge request's title and body, reading a pipeline, and the shared types.
automated_review.pyWhich automated reviewer a repo expects.
detect.pyWhat kraft repo connect proposes as a repository's setup and test commands.
adapters/beads.py, intake.pybd calls, and auto-intake from bd ready.
triggers.pyCron schedules from intake.yaml.

State and configuration

PathWhat it does
db.pyThe schema, its migrations, and the single-writer Database.
events.pyAppending to and reading the events table.
store/Every query, by table: work_items, chain, gates, sessions, counters, budget, review, repos, forks, intake. _common.py holds the rule that an ended item never becomes runnable.
paths.py$KRAFT_HOME and the run/ layout.
config.py, config_schemas.pyReading and writing the YAML files, and their JSON Schemas for editors.
capabilities.pyWhat this version can do that an older seeded config cannot.
index/The search index: chunking, local embeddings, ingest, and the query service.
analytics.pyThe numbers behind the Analytics view.
archive.pyAuto-archive of old ended items.
notify.pyOutbound notifications.
auth.pyPassword login and sessions for off-localhost access.
doctor.py, update.py, init.pykraft admin doctor, update and init.
pidfile.pyrun/kraft.pid: which process is this run dir's server, held under a lock.
intent.pyChecks the intent tree in docs/intent/ (a CI check, not part of the server).

Outside src/kraft/: the web UI is in frontend/src/ng/ (a folder per area), the shipped default configuration is in config/, the agent plugins are in plugins/, the VS Code extension is in vscode/, and contributor scripts are in dev/.

Workspace members

A sandbox covers a workspace's members as it covers the root. A member is a worktree of its connected repository (_setup_submodules in builtins.py), so host git in it reads that repository's config, not a git directory under the root's worktree. It also reads the member's own config.worktree when that repository sets extensions.worktreeConfig.

What a sandboxed container sees of a memberEnforced by
Its refs go through a ref store of its own.prepare_stores in worker/refstore.py
Its .git, and the commondir, gitdir and config.worktree of its admin directory, are read-only. They are mounted from paths derived from the connected repository, never read from the member's .git._gitdir_mounts in worker/backends/docker.py
Each directory from the worktree down to the member is mounted onto itself, so no container can rename it and put another .git in the member's place._pin_path in worker/backends/docker.py

Before host git runs in a member, Kraft checks it against the checkout Kraft made:

  • For a sandboxed item, refuse_planted_repos in executor/stops.py runs the check (foreign_members in worker/sandbox.py). A task's launch mounts exactly the checkout that check returned.
  • Every other sandboxed launch takes its checkout from sandbox_checkout. These are a gate review, an escalation turn, a review reply and the setup command. It runs the same check and leaves out any member that fails it, so the launch does not start.

Where to change things

ToChange
Add a CLI verb or MCP toolA function in client/actions.py or client/reads.py, its verb in cli/item.py or cli/view.py, its tool in mcp.py, and the CLI reference.
Add an API routeA handler on api_router in the matching api/routes/*.py. A new module is imported in api/__init__.py.
Add a harnessA YAML file in harnesses/. See Add or override a harness.
Add a builtin actionA member of BuiltinAction in templates/models.py, its branch in executor/dispatch.py, and the work in builtins.py.
Add a forge action or backendForgeAction in templates/models.py and adapters/forge/run.py; a backend beside gh.py and glab.py.
Change what a Kraft add-on may carryLIMITS and problems in addons/update.py, the layout and limits in addons/manifest.py and addons/fetch.py, and Add-ons and collections.
Change a shipped chain or library componentconfig/chains/*.yaml and config/library.yaml at the repo root. Run kraft admin templates lint.
Change what an agent is toldThe skill in skills/<name>/SKILL.md, or Kraft's own notes in executor/prompts.py.
Add a policy.yaml keyPolicyInput and Policy in policy.py, the default in config/policy.yaml, and policy.yaml.
Add a repos.yaml keyRepoEntry in config.py, and repos.yaml.
Change the databaseA new numbered migration in db.py, and the queries in store/.
Change how a stop is handledexecutor/walk.py and executor/stops.py.
Add a status transitionThe write in store/, through write_status in store/_common.py, and the door in api/routes/lifecycle.py.
Add a doctor checkdoctor.py.
Change a screenIts area's folder under frontend/src/ng/ (board/, item/, review/, templates/, settings/ and so on).
  • Architecture: how these parts fit together, and where each trust boundary is enforced.
  • Contributing: the steps to take before you open a pull request.
Copyright © 2026