# Agent-native contract (/docs/agents/contract)



Bowline is agent-native: any action you can take, a trusted coding agent can take
too, through the same CLI. The CLI is the local source of truth for automation.
This page is the contract an agent depends on: how to discover commands, read
structured workspace context, run bounded exploration, and retry mutations
safely.

If you're a person handing work to an agent, start with
[work with coding agents](/docs/guides/working-with-agents). This page is for the
agent side.

## Start here [#start-here]

An agent should begin every session by discovering the contract and reading
state, rather than scraping help text or guessing argument shapes.

```bash title="Agent start sequence"
bowline contract --json
bowline help --json
bowline status --json
```

`bowline contract --json` is canonical. It returns the CLI version, protocol
version, event schema version, package contract source, and every command
descriptor: group, usage, options, examples, JSON output type, side-effect
level, support for `--json`, `--dry-run`, and `--idempotency-key`, bounded-output
controls, and related commands. `bowline schema --json` is an alias for the same
output.

## Structured context: AgentContextV1 [#structured-context-agentcontextv1]

When you start a lease, Bowline compiles the task into a structured context
bundle. This bundle, not prose, is the contract between Bowline and any agent
runner, MCP server, devcontainer, or local socket consumer.

```bash title="Lease context"
bowline agent start ~/Code/acme/web --task "fix the auth callback race" --json
bowline agent context --lease <id> --json
bowline agent prompt --lease <id>
```

The context names the workspace and project identity, the base snapshot and
freshness, the lease (task, read and write scope, hydration budget, expiry, and
output target), env metadata, policy, index versions, and current status. It is
designed so an agent has everything it needs without secret values ever entering
prompt text.

<Callout type="warn" title="Secrets never enter prompts">
  The prompt receives env key names, source files, profiles, materialization
  mode, and grant identifiers, never secret values. Runtime env and tools
  receive actual secret values only when policy permits. Treat any secret in
  prompt text as a bug.
</Callout>

## JSON output and errors [#json-output-and-errors]

Every command except the interactive TUI supports `--json`. In JSON mode,
failures use a stable `CommandErrorOutput` envelope on stdout with a non-zero
exit code. Parse it rather than the human text.

The envelope includes `contractVersion`, `command`, `generatedAt`, `status`, and
a top-level `nextActions`. It also carries an `error` object with `code`,
`message`, and `recoverability`, plus optional `remediation`, `details`,
`retryAfterSeconds`, and `correlationId`. Use `error.recoverability` and
`retryAfterSeconds` to decide whether and when to retry.

## Bounded exploration [#bounded-exploration]

Exploration is bounded by default so output stays predictable for an agent's
context window. `bowline search` and `bowline symbols` default to a limit of 20,
reject limits above 100, and page with opaque `v1:<offset>` cursors, emitting
`nextCursor` while more results exist.

```bash title="Bounded search"
bowline search "auth callback" ~/Code/acme/web --limit 20 --json
bowline search "auth callback" ~/Code/acme/web --cursor v1:20 --json
bowline symbols AuthCallback ~/Code/acme/web --path-prefix src --json
```

Prefer index-backed `search` and `symbols` over broad recursive reads. Broad
reads require index-backed exploration first.

## Safe, retryable mutations [#safe-retryable-mutations]

Mutations an agent might retry support `--dry-run` and `--idempotency-key`.

* `--dry-run` returns a preview and changes nothing; its result includes the
  exact command to apply the change.
* `--idempotency-key <key>` makes a non-dry-run mutation replay-safe. Replaying
  the same key with the same normalized request returns the stored result with
  `replayed: true`. The request identity includes the working directory for
  relative targets and target-affecting globals such as `--socket`. A different
  request under the same key returns an `idempotency_conflict` error.

Recovery `verify` and `use` read sensitive stdin and reject idempotency keys.

## Hard safety invariants [#hard-safety-invariants]

These rules live in validators and storage boundaries, not in agent judgment.
They hold no matter what a prompt says.

* Direct leases may write the real project path; [Work View](/docs/concepts/work-views)
  leases may not write the main project until you accept the work.
* Work-view output never applies to the main project without review.
* Unclassified or blocked local files never become synced state without policy.
* Project env never travels or rests unencrypted remotely, and secret values
  never enter prompt text.
* Watcher scans never hydrate the whole workspace.
* Policy changes require explicit user or organization approval.
* Degraded workspace state stops risky agent actions.
* Broad recursive reads require index-backed exploration first.

## Atomic tools, not workflows [#atomic-tools-not-workflows]

Agent behaviors compose small, atomic, structured tools: inspection,
exploration, hydration, scoped writes, execution with receipts, and review.
Bowline deliberately does not ship workflow-shaped commands like
`prepare_pull_request` or `sync_env_and_run_tests`. New behaviors belong in
prompts and recipes that compose the primitives, not in new CLI commands.

## Next steps [#next-steps]

* [Agent workflows](/docs/agents/workflows): end-to-end lease, review, and
  remote-bootstrap flows.
* [Agent leases](/docs/concepts/agent-leases): the lease model and lifecycle.
* [CLI overview](/docs/cli/overview): conventions that apply to every command.
