grith.aidocs

grith exec

Supervise an external CLI tool with OS-level syscall interception.

grith exec [OPTIONS] -- <COMMAND> [ARGS...]

Spawn <COMMAND> (or attach to an existing PID) under grith's syscall-level supervisor. Every interesting syscall the process tree makes routes through the filter pipeline before execution.

This is the workhorse command — almost every real grith session starts with grith exec.

Synopsis

grith exec [--profile <NAME>] [--zone <NAME>]
           [--attach <PID>]
           [--syscall-log <FILE>] [--trace-syscalls-jsonl <FILE>]
           -- <COMMAND> [ARGS...]

The double-dash (--) is required when the supervised command has its own flags. It tells grith where its options stop and the target command's begin.

Options

FlagTypeDefaultDescription
--profile <NAME>stringgenericSupervisor profile to use. See Choose your agent.
--zone <NAME>stringnoneBind the session to a containment zone.
--attach <PID>u32Attach to an existing process by PID instead of spawning. Useful for already-running agents.
--syscall-log <FILE>pathLog every syscall request and decision to a file (human-readable).
--trace-syscalls-jsonl <FILE>pathWrite raw pre-filter syscall forensics to a JSONL file. Heavyweight; use for forensics.

Examples

Spawn Claude Code with the matching profile:

grith exec --profile claude-code -- claude

Wrap a plain bash session:

grith exec --profile generic-cli -- bash

Attach to an already-running Python REPL:

grith exec --attach 17421

(The target must be a descendant of a process you can ptrace. See Installation: permissions.)

Forensic record-and-replay:

grith exec \
    --profile claude-code \
    --trace-syscalls-jsonl ~/.cache/grith/last.jsonl \
    -- claude

# Later, audit the recorded session against the profile:
grith profile audit --profile claude-code --trace ~/.cache/grith/last.jsonl

Use a containment zone:

grith exec --profile claude-code --zone dayjob -- claude

What it does, in order

  1. Connects to the local daemon if one is running (thin-client mode). Otherwise runs the filter pipeline in-process.
  2. fork() the target process; child sets up its own seccomp filter.
  3. ptrace(PTRACE_SEIZE) from the parent to attach without a stop.
  4. Child execve()s the target binary; the supervisor takes over.
  5. Every interesting syscall (configured set: file ops, exec, sockets, network) traps to the supervisor.
  6. The call shape is sent through the filter pipeline.
  7. Decision (ALLOW / QUEUE / DENY) is applied via ptrace(PTRACE_SYSCALL) or register rewriting.

PTY forwarding

For interactive targets (REPLs, shells, TUI agents) grith allocates a PTY pair and shuttles bytes transparently. Input editing, ANSI escapes, and signals (Ctrl-C, Ctrl-Z) work exactly as if grith weren't in the loop.

Scrolling and copy-paste

The supervisor TUI captures the mouse so the scroll wheel drives grith's scrollback (otherwise the host terminal turns the wheel into arrow keys that agents reject). Mouse capture also means a plain click-drag selection is owned by grith, so the keys below switch between scrolling and selecting:

KeyAction
Shift+PgUp / Shift+PgDnScroll the terminal scrollback.
Ctrl+TToggle select mode — drops mouse capture and freezes the screen so you can drag-select and copy text. Press again to resume scrolling.
Ctrl+LToggle the audit-log panel.

While select mode is on, the footer shows SELECT MODE — drag to copy · wheel-scroll paused, and repaints are frozen so your selection isn't wiped by live output. A permission prompt overrides the freeze so a queued decision is never hidden.

Exit behaviour

  • Exits with the target's exit code when the target exits normally.
  • Sends SIGTERM to the supervised tree on Ctrl-C; SIGKILL after a 5s grace period.
  • Records the session-end event in the audit log.

See also

Last updated: 2026-05-14Edit this page on GitHub →
© 2026 grith. All rights reserved.