Docs

In your agent

Agent Controls ​

Check coding agents' work before they finish, pause risky commands, share codebase memory and record which agent made each change.

A single coding agent can run risky commands, forget what the team learned and leave no record of what it did; agent controls fix all three, for teams using AI coding agents.

Agent controls put Bumpkit inside a coding agent's loop. The agent's work is checked before it finishes, risky shell commands wait for a person, what the team learned about the code reaches every new session, and each change records which agent, model and session produced it.

Most of these run as agent hooks. To install the hooks for Claude Code, Cursor, Codex, Gemini CLI, Windsurf and Cline, see Agent Hooks. Every command below is also listed in the CLI Reference, and every endpoint in the API Reference.

Feature Flag Commands MCP tools Endpoints
Agent guard agent_guard bumpkit guard guard none
Codebase memory codebase_memory bumpkit memory, bumpkit recall recall, remember, forget /v1/memories
Pause risky commands agent_pause bumpkit pause pause /v1/agent/decisions
Memory approval memory_approval bumpkit memory pending, approve, reject memory_pending, memory_approve, memory_reject /v1/memories/pending
Agent forensics agent_forensics bumpkit provenance show provenance_show /v1/checks/{id}/provenance
AI change provenance change_provenance bumpkit provenance provenance_show, provenance_attest /v1/provenance/events, /v1/checks/{id}/provenance
Agent scorecards agent_scorecards bumpkit scorecards agent_scorecards /v1/scorecards

Agent guard ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: agent_guard.

bumpkit guard runs the Release Gate on the agent's uncommitted and committed changes before the agent finishes or pushes. When the gate fails or needs approval, the agent is sent back with the reasons.

Terminal
bumpkit guard
bumpkit guard --base origin/main
Flag Default Meaning
--base Where this branch left the default branch The ref to compare against
--hook none claude, cursor, codex, gemini, windsurf or cline: run as that agent's finish hook

What it does:

  1. Finds the base: the merge base of HEAD with origin/HEAD, origin/main, origin/master, main or master. If the branch hasn't left the default branch, it uses the latest tag.
  2. Takes the diff from the base to your working tree, including uncommitted changes. An empty diff passes without a message.
  3. Runs a fast gate with the bumpkit.yml from the base ref, so an agent can't loosen the policy in the change it is checking.
  4. On a pass, it exits 0. Run directly, it prints nothing. As a Codex hook it prints {}, and as a Cline hook {"cancel":false}.

When the gate fails, the message lists only the proven (deterministic) high-severity findings, with where each one is, and tells the agent to explain any false positive in its final message. When the gate needs approval, it lists each rule that needs a person and tells the agent not to work around it.

Run directly, bumpkit guard prints the message to stderr and exits 1 when the gate fails or fix tasks are open. When the change only needs approval, it prints which approval the push will need and exits 0. With --hook, it prints the reply that agent expects. Every hook exits 0 except Windsurf's, which blocks by exiting 2:

Hook Reply Exit code
--hook claude {"decision":"block","reason":"..."} 0
--hook cursor {"followup_message":"..."} 0
--hook codex {"decision":"block","reason":"..."} 0
--hook gemini {"decision":"deny","reason":"..."} 0
--hook cline {"cancel":true,"errorMessage":"...","contextModification":"..."} 0
--hook windsurf The message on stderr 2

See Agent Hooks for where each hook runs.

In hook mode, the guard runs once per stop: it skips when Claude Code or Codex reports stop_hook_active, when Cursor's loop_count is above 0 or its status isn't completed, and when Gemini reports stop_hook_active. The Windsurf hook runs only before a git push, and the Cline hook only before attempt_completion. If there is no API key, Bumpkit is unreachable or the feature is off, the guard prints a note to stderr and exits 0, so it never blocks an agent on its own failure. The Codex, Gemini, Windsurf and Cline hooks also need the agent_hooks_extended flag (Beta); without it they print a note and let the agent finish.

With Close the loop on (Beta, flag close_the_loop), the guard also sends the current branch. While fix tasks are open on that branch, it sends the agent back with each task, its places and pull requests, even when the gate passes.

The git pre-push hook from bumpkit hooks install --git runs bumpkit guard, so proven problems stop a push from any agent or person. See Agent Hooks.

Codebase memory ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: codebase_memory.

Codebase memory stores what agents and people learned about a repository, by path: decisions, pitfalls, incidents and notes. Agents recall it when they start work in an area, together with the recent releases that changed that area.

Save a memory ​

Terminal
bumpkit memory add "Webhook handlers must stay idempotent; GitHub retries on timeout." \
  --kind decision --path services/webhooks/github.go
Flag Default Meaning
--kind note note, decision, pitfall or incident
--path The whole repository The file or directory it's about
--repository The origin remote The repository URL

Rules for a memory:

  • The body is required and at most 2000 characters.
  • Duplicates are merged. Saving the same text again for the same repository, path and kind (ignoring case and whitespace) doesn't create a second memory. It refreshes the existing one's date and author instead.
  • Provenance. Each memory keeps who saved it (author, such as cli or the agent's name) and when.

Recall memories ​

Terminal
bumpkit memory list services/api
bumpkit recall --path services/api

bumpkit memory list [PATH] prints a table of IDs, kinds, paths and text. bumpkit recall prints the same memories as text an agent can read: approved swarm lessons first when swarm_lessons is on, then the memories with their kind, author and ID, then the five finding kinds recent releases there were flagged for most.

Flag (bumpkit recall) Default Meaning
--path The whole repository A file or directory
--hook none claude, cursor, codex, gemini or cline: run as that agent's session start hook. codex, gemini and cline also need agent_hooks_extended

Recall for a path returns memories saved for that path, for any parent directory, for anything under it, and for the whole repository. Recall is trimmed to fit in an agent's context.

Memories are ordered decisions first, then pitfalls, incidents and notes, newest first within each kind. The API and the recall MCP tool also return the last 10 releases that changed the path, what they were flagged for, and which agents wrote them. The bumpkit recall text includes only the flagged finding kinds.

With --hook claude or --hook gemini, bumpkit recall prints a SessionStart reply with the text as additionalContext. With --hook cursor, it prints {"additional_context":"..."}, with --hook cline {"cancel":false,"contextModification":"..."}, and with --hook codex the plain text. The text ends by telling the agent to respect the decisions and pitfalls, call recall before changing an area, save what the next agent should know with remember, and forget memories that are no longer true.

Forget a memory ​

Terminal
bumpkit memory forget 3f2c9a1e-8b7d-4c2a-9e1f-6a5b4c3d2e1f

Use it when the code changed and a decision or pitfall no longer applies. The memory is deleted.

MCP tools ​

The MCP server adds these tools when codebase_memory is on:

Tool Arguments What it does
recall path, repository Memories and recent releases for a path
remember body (required), path, kind, author, repository Saves a memory
forget id (required), confirm Deletes a memory by the ID recall returned; nothing is deleted until you pass confirm: true after the user agrees

repository is owner/name and defaults to the origin remote of the current directory.

API ​

Endpoint What it does
POST /v1/memories Save a memory: repository, path, kind, body, author. Returns 201
GET /v1/memories?repository=...&path=... Recall memories, releases, flagged finding kinds and agents
DELETE /v1/memories/{id} Forget a memory. Returns 204, or 404 MEMORY_NOT_FOUND

Pause risky commands ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: agent_pause.

bumpkit pause checks each shell command or file access before the agent runs it. It allows it, asks a person to confirm, or denies it with a reason and advice on what to do instead.

How the hook works ​

The pause hook runs before a tool call:

Agent Hook event What it checks
Claude Code PreToolUse, matcher Bash|Read|Write|Edit|MultiEdit|NotebookEdit Shell commands and the file paths of reads and writes
Cursor beforeShellExecution Shell commands
Codex PreToolUse, matcher ^(Bash|apply_patch)$ Shell commands and the files a patch adds, updates, deletes or moves

Install it with bumpkit hooks install (see Agent Hooks). For each call:

  1. Every part of the command, including pipelines, && chains and sh -c strings, is checked against the built-in rules and your agent: policy.
  2. If everything is allowed, the hook returns at once.
  3. Otherwise the decision is recorded in Bumpkit with the command redacted. With agent.remote: true, an ask waits for a teammate to approve or deny it in Bumpkit.
  4. The hook replies with allow, ask or deny and the reason.
Hook Reply
--hook claude hookSpecificOutput with permissionDecision and permissionDecisionReason
--hook cursor {"permission":"...","user_message":"...","agent_message":"..."}
--hook codex permissionDecision: deny with the reason. Codex hooks can't ask, so an ask is stopped and the agent is told to ask the user or to have it approved in Bumpkit with agent.remote

The policy comes from bumpkit.yml on the default branch (origin/HEAD, then origin/main, origin/master, then HEAD), never from the working copy, so an agent can't loosen it by editing the file. The pause hook never allows everything: when there is no API key, Bumpkit is unreachable or the feature is off for your workspace, it checks with the built-in rules plus your agent: section, prints a note to stderr, and records nothing in Bumpkit. If bumpkit.yml is invalid, the default rules apply.

With agent budgets and scopes on (Beta, flag agent_budgets), bumpkit pause --hook claude also denies a Write, Edit, MultiEdit or NotebookEdit call on a file outside the agent's paths_allow, inside its paths_deny, or in an area its areas_deny lists, with the reason shown to the agent. The agent is matched by BUMPKIT_AGENT_ID (or BUMPKIT_AGENT) and as claude-code. This check needs Bumpkit to be reachable.

Check a command by hand ​

Terminal
bumpkit pause git push --force origin main

It prints allow and exits 0, or prints ask: <reason> or deny: <reason> and exits 1. It works the same without an API key, using the built-in rules.

What counts as risky ​

Rule Default Matches
rm_rf ask rm -r on a path outside a temporary or build directory
rm_rf_root deny rm -r on /, the home directory, the repository root or a system directory
force_push deny git push --force or a branch delete on a protected branch
git_reset_hard ask git reset --hard, which throws away uncommitted work
git_clean ask git clean -f, which deletes untracked files
sql_drop ask DROP, TRUNCATE or an unfiltered DELETE sent to a database client
infra_apply ask terraform, tofu or pulumi apply and destroy
kubectl_delete ask kubectl delete or drain, helm uninstall
pipe_to_shell ask A downloaded or decoded script piped into a shell or interpreter
chmod_777 ask chmod -R that makes files world-writable
secret_write ask A write to .env, a key or a secrets file
credential_file ask Reading or copying a credential file such as .env, ~/.ssh or ~/.aws
package_publish ask Publishing a package or pushing an image
prod_database ask A database URL whose host isn't local
self_approval deny An agent approving or rejecting Bumpkit memories, lessons or Approvals items
agent_scope deny An agent writing outside the paths and areas agents: gives it
too_complex ask A command nested too deeply to check

Protected branches default to main, master, trunk, production, prod, release/* and releases/*.

Policy keys ​

YAML
agent:
  deny: [infra_apply, "npm publish *"]
  ask: ["make deploy*"]
  allow: [git_reset_hard]
  protected_branches: [main, "release/*"]
  remote: true
  timeout: 60s
Key Default Meaning
deny none Rule IDs to deny, or command patterns
ask none Rule IDs to ask about, or command patterns
allow none Rule IDs to allow, or command patterns
protected_branches The list above Branch names or globs force_push protects
remote false Let a teammate approve an ask in Bumpkit while the agent waits
timeout 30s How long to wait for a remote approval, between 5s and 120s

Each entry is a rule ID from the table above or a command pattern where * matches anything and ? one character. A bare word that isn't a rule ID is rejected, so write a pattern with a space or *, like "deploy *". A pattern in deny beats everything. A pattern in allow allows the command unless a rule it hits is listed in deny. See bumpkit.yml: agent for the full schema.

Remote approval ​

With remote: true, an ask is recorded as pending and the hook waits up to timeout. A teammate approves or denies it on the Approvals page in the dashboard. If no one decides in time, the agent gets ask and the human at the terminal decides.

Endpoint What it does
POST /v1/agent/decisions Record a decision: repository, agent, session, tool, command, command_hash, rules, reason, decision, remote, timeout_seconds. Rate limited to 240 per minute per key
GET /v1/agent/decisions/{id} A decision's status: pending, approved, denied or expired

Memory approval ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: memory_approval. Needs codebase_memory.

With memory approval on, memories saved through the API wait as pending until a person approves them. Only approved memories are recalled.

Turn it on for the whole workspace:

Terminal
bumpkit settings set --memory-approval on

Or for one repository, on its default branch:

YAML
memory:
  require_approval: true

Bumpkit reads the repository's default-branch bumpkit.yml through the GitHub App. Without the App, only the workspace setting applies. See bumpkit.yml: memory.

Review pending memories:

Terminal
bumpkit memory pending
bumpkit memory approve 3f2c9a1e-8b7d-4c2a-9e1f-6a5b4c3d2e1f
bumpkit memory reject 3f2c9a1e-8b7d-4c2a-9e1f-6a5b4c3d2e1f

A rejected memory is never recalled. A key can't review a memory saved with a key of the same person, or with a key that was since deleted, so review your own agent's memories in the dashboard, or ask a teammate to use their key. The self_approval pause rule denies an agent that tries to run these commands. You can also review memories on the Approvals page in the dashboard.

Endpoint What it does
GET /v1/memories/pending Pending memories, optionally for one repository
POST /v1/memories/{id}/approve Approve a pending memory
POST /v1/memories/{id}/reject Reject a pending memory

Agent forensics ​

Beta, early access. A workspace without access gets the provenance page without this section. Flag: agent_forensics.

Agent forensics answers what an agent did on a change. It adds a timeline to bumpkit provenance show CHECK_ID, the provenance_show MCP tool, GET /v1/checks/{id}/provenance and a release check's provenance page: agent sessions, what the guard allowed or refused, the check, the gate decision and approvals, and what happened in production.

Each entry says where it came from. Reported by the agent came from its hooks, so a compromised agent could leave it out or change it. Recorded by Bumpkit came from Bumpkit's own check and gate, on a diff it fetched itself. Sent by a client, from its own diff came through bumpkit gate, the API or MCP, and Bumpkit can't confirm that diff matches the commit.

The timeline also lists what it observed that deserves a look. These never block a release on their own:

Signal What it means
no_session The repository reports agent sessions, but none matches this change. A person may have written it, or an agent ran without hooks
denied_actions Bumpkit or a person denied some of the agent's actions while it worked on this change
unauthenticated_session A session didn't come from an authenticated reporter

AI change provenance ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: change_provenance.

Provenance records, for each release check, which agent made the change: its version and model, the session, the tools it used, the human sponsor, optional redacted prompt summaries, the approvals and the verification evidence.

Record provenance ​

Install agent hooks first (see Agent Hooks), then turn on recording in the repository:

Terminal
bumpkit provenance enable
bumpkit provenance enable --prompts
bumpkit provenance disable

enable adds bumpkit provenance record --hook AGENT to each agent hook file it finds. --prompts also sends a redacted summary of each prompt; it is off by default. bumpkit hooks install --provenance [--prompts] does the same while installing.

bumpkit provenance record --hook AGENT reads the hook payload on stdin. AGENT is claude, cursor, codex, gemini, windsurf or cline. Each event is sent with the session ID, the agent version and model when the agent reports them, and the repository, branch and head commit. The sponsor comes from the API key, never from the event: a key tied to a person records that account, shown with its current email and marked verified, and a key tied to no person records key:<id>, never verified. A session stays bound to the account or key that started it. An event for it from any other account or key gets 409 PROVENANCE_SESSION_CONFLICT, and viewers can't record events. The agent name, tools and prompts are reported by the agent and aren't verified:

Event Sent when
start A session or task starts or resumes
tool A tool, shell command, file edit or MCP tool ran (MCP tools as mcp:server/tool)
prompt You submit a prompt. The text is sent only with --prompts, with secrets redacted and cut to 280 characters
end The session or task ends

Recording never blocks the agent.

When a release is checked, Bumpkit links the agent sessions that made it.

Name the agent, model, session or sponsor yourself with these commit trailers (case-insensitive):

Trailer Recorded as
Bumpkit-Agent, Agent, AI-Agent, Generated-By Agent
Bumpkit-Model, Agent-Model, AI-Model, Model Model
Bumpkit-Session, Agent-Session, Session-Id Session
Bumpkit-Sponsor, Sponsored-By, Human-Sponsor Sponsor
Co-Authored-By Co-author
Signed-Off-By Sign-off
Reviewed-By, Approved-By, Acked-By, Bumpkit-Reviewer Reviewer

View and attest ​

Terminal
bumpkit provenance show CHECK_ID
bumpkit provenance attest CHECK_ID

show prints the provenance record as JSON, including the agent forensics timeline when that flag is on. attest prints an in-toto statement (https://in-toto.io/Statement/v1) with predicate type https://bumpkit.dev/attestation/change-provenance/v1. Each release in the dashboard has a provenance view at /checks/{id}/provenance, and the compliance evidence export includes the attestations.

Endpoint What it does
POST /v1/provenance/events Record an event: agent, session_id, event, tool, prompt, model, agent_version, repository, branch, head_sha. Rate limited to 600 per minute per key
GET /v1/checks/{id}/provenance The provenance record for a release check
GET /v1/checks/{id}/attestation The in-toto attestation
GET /v1/provenance/key Whether attestations are signed, and the Ed25519 public key and key ID when they are

Agent scorecards ​

Beta, early access. A workspace without access gets 403 FEATURE_EARLY_ACCESS and a link to request it. Flag: agent_scorecards.

Scorecards show how each coding agent's releases fared: how many shipped clean, were blocked or needed approval, how many proven high-severity problems they carried, and what they were flagged for most. Releases with no agent detected show as agent none.

Terminal
bumpkit scorecards --days 90

--days defaults to 30. The same data is on the Reports tab of Insights in the dashboard, next to the committed by and written by matrix, at GET /v1/scorecards?days=N, and in the agent_scorecards MCP tool (days, at most 365).

↑↓ to move, Enter to open