Skip to content

Agent Integrations

ActPlane can protect an agent in two ways:

  • Run the agent under ActPlane directly with actplane run.
  • Let the agent start normally and use hooks or MCP to receive corrective feedback and auto-attach to the parent process.

The kernel remains the authority. Hooks and MCP only carry ActPlane's feedback back into the agent workflow.

Direct Launch

Use this when you want strict launch-time enforcement and a clear process tree:

actplane init --template no-git-branch --out actplane.yaml
actplane compile --explain
actplane doctor
sudo -E actplane run -- claude -p "review this repository"

actplane run loads the eBPF engine, seeds the launched command as the protected runtime root, drops the target command back to the invoking user by default, and writes feedback to .actplane/last-violation.txt.

Codex Hook

Install the project-local Codex hook:

actplane init --with-codex

This writes .codex/hooks.json with a PostToolUse hook that runs:

actplane feedback-hook

When a rule has matched since the last hook invocation, the hook returns an additionalContext payload to the next model turn. That context contains the rule name, effect, target process, and because reason from the policy.

Verify:

actplane doctor
actplane feedback-hook --help

If .codex/hooks.json already exists, ActPlane keeps it unless the existing hook is already ActPlane-managed or you pass --force:

actplane init --with-codex --force

Remove:

rm -f .codex/hooks.json
rm -f .actplane/feedback-hook.state.json

If .codex/hooks.json contains other project hooks, remove only the actplane feedback-hook entry instead of deleting the whole file.

Claude Code Hook

Claude Code can use the same feedback hook through project settings:

{
  "hooks": {
    "PostToolUse": [
      {
        "matcher": "*",
        "hooks": [
          { "type": "command", "command": "actplane feedback-hook" }
        ]
      }
    ],
    "PostToolUseFailure": [
      {
        "matcher": "*",
        "hooks": [
          { "type": "command", "command": "actplane feedback-hook" }
        ]
      }
    ]
  }
}

ActPlane does not currently rewrite .claude/settings.local.json for you. Keep the command as actplane feedback-hook so the project uses the actplane found on PATH.

MCP Auto-Attach

Install project-local MCP config:

actplane init --with-mcp

This writes .mcp.json:

{
  "mcpServers": {
    "actplane": {
      "type": "stdio",
      "command": "actplane",
      "args": ["mcp", "--auto-attach-parent"]
    }
  }
}

When the agent starts the MCP server, --auto-attach-parent tries to load the eBPF engine and seed the parent agent process. The MCP server exposes resources for the active policy and latest feedback, and it can accept controlled child domain operations when the engine is running.

Verify:

actplane doctor
actplane mcp --help

Project MCP vs Global MCP

Prefer the project .mcp.json generated by:

actplane init --with-mcp

Project MCP keeps the policy and engine selection tied to the repository. Use a global Codex MCP entry only if your Codex build does not read project MCP configuration:

codex mcp add actplane -- actplane mcp --auto-attach-parent

Do not keep both project and global ActPlane MCP entries active for the same session. actplane doctor warns when it sees both.

All-in-One Setup

For a new repository:

actplane init --template no-git-branch --out actplane.yaml
actplane init --all
actplane compile --explain --report-out docs/actplane-review.txt
actplane doctor

--all writes project policy integration files:

  • .codex/hooks.json for actplane feedback-hook.
  • .mcp.json for actplane mcp --auto-attach-parent.
  • AGENTS.md guidance telling agents to treat ActPlane feedback as authoritative.

Use --force only when replacing ActPlane-managed setup files is intentional.

Feedback Files

During enforced runs, ActPlane writes:

.actplane/last-violation.txt
.actplane/feedback-hook.state.json

last-violation.txt is human-readable. It records the latest rule match and the corrective reason that hooks forward to the agent. The hook state file tracks offsets so the agent receives only new feedback.

Useful environment overrides:

ACTPLANE_FEEDBACK_FILE=/tmp/actplane-feedback.txt
ACTPLANE_HOOK_STATE=/tmp/actplane-hook-state.json

Attach an Already-Started Agent

Use foreground attach when an agent is already running and you want future events protected from this point forward:

sudo -E actplane attach --pid <pid>

Attach is post-hoc. It does not reconstruct file, network, label, or lineage history from before the attach. Prefer actplane run or MCP auto-attach for strict launch-time enforcement.

Bind an already-started process into a child domain of a running MCP/watch engine:

actplane attach --pid <pid> --child-domain --domain-id <domain-id>
actplane attach --pid <pid> --child-domain --delta child-policy.dsl

Child Domains from a Running Engine

Start a parent engine:

actplane watch

Then launch or control children from another shell:

actplane control status
actplane control launch-child --delta child-policy.dsl -- codex
actplane control children
actplane control logs --child-id <id>
actplane control stop --child-id <id>

Append a runtime policy delta to an existing domain:

actplane control delta add --target-id <domain-id> --delta policy-delta.dsl

If the project policy requires runtime-delta approval metadata, include it:

actplane control delta add \
  --target-id <domain-id> \
  --delta policy-delta.dsl \
  --approved-by alice \
  --approval-ref REVIEW-123 \
  --generated-by codex

Runtime deltas are append-only. They can tighten a domain but cannot remove or weaken inherited policy.

Troubleshooting

Run:

actplane doctor
actplane compile --explain --report-out docs/actplane-review.txt

Common findings:

  • BPF-LSM is unavailable: block rules cannot pre-deny operations. Use notify or kill where appropriate, or enable BPF-LSM on the host.
  • Hook is missing: run actplane init --with-codex.
  • Project MCP is missing: run actplane init --with-mcp.
  • Both project and global MCP are configured: keep only one ActPlane MCP entry.
  • Attach is too late: relaunch the agent with actplane run for strict launch-time history.