> ## Documentation Index
> Fetch the complete documentation index at: https://opentrain.ai/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Follow and Improve the Agent Guide

> Read the Agent Guide once, follow exact Playbook deltas, propose changes as an agent, and publish as a human across CLI, MCP, SDK, and the API.

This guide lists the exact operations behind the [Agent Guide](/docs/developers/concepts/agent-guide) on every official surface. Most of the loop happens without you asking for it: the sync envelope directs the one guide read and names the exact delta when guidance changes. Use the operations below when you need the full document, a specific version, a proposal, or a publication.

## Before you start

You need:

* an employer account or employer team membership with access to the job;
* `jobs:read` to read the guide, Playbook, and proposals;
* `jobs:write` to submit or resolve proposals; and
* a human job-manager account to publish.

<Warning>
  These operations require CLI 0.26.0+, MCP 0.26.0+, or SDK 0.24.0+, and a
  deployment whose `GET /api/public/v1/capabilities` response reports
  `job_operations` as `available`. Older packages do not expose them.
</Warning>

## The loop an agent follows

<Steps>
  <Step title="Let the bootstrap direct the read">
    Enter the job with the normal context read. The response's
    `sync.nextOperations` ends with `job_operations.agent_guide.get`. Read the
    Agent Guide once and keep its `contextRevision`, `checksum`, and the
    Playbook `playbookVersion` you now hold.
  </Step>

  <Step title="Follow the delta only when it is named">
    On later covered calls, act on `recommendation.agent_guide_changed` when it
    appears. It names the exact `fromVersion` and `toVersion`. Fetch that
    Playbook delta, apply the added and changed sections, and drop every id in
    `removedSectionIds`. If the recommendation is absent, your guidance is
    current.
  </Step>

  <Step title="Respect precedence">
    Typed policies, workflow gates, decisions, exceptions, and the Work Catalog
    outrank Playbook prose. When the Playbook disagrees with a typed record,
    raise it to the responsible human.
  </Step>

  <Step title="Propose, do not publish">
    When guidance is missing, wrong, or outdated, submit a proposal with
    `basePlaybookVersion` equal to the current head. A human reviews it, applies
    it to the shared draft, and publishes.
  </Step>

  <Step title="Acknowledge only what you received">
    Checkpoint the revision the envelope actually delivered to you. Never
    acknowledge a revision you have not received.
  </Step>
</Steps>

## CLI

```bash theme={null}
# The composite Agent Guide (typed projection + published Playbook + open proposals)
opentrain manager agent-guide get --job-id <job-id> --format markdown

# Published Playbook head, history, one version, and an exact delta
opentrain manager playbook get --job-id <job-id> --format markdown
opentrain manager playbook versions --job-id <job-id> --limit 50
opentrain manager playbook version --job-id <job-id> --playbook-version 3
opentrain manager playbook delta --job-id <job-id> --from-version 3 --to-version 5

# Proposals (agent path; RECOMMENDED, never enforced)
opentrain manager playbook proposals list --job-id <job-id> --status OPEN
opentrain manager playbook proposals submit --job-id <job-id> \
  --idempotency-key escalation-window-v1 \
  --kind SECTION_UPSERT --dedupe-key escalation.update \
  --base-playbook-version 5 --section-id escalation \
  --title "Clarify the escalation window" \
  --proposed-section-json '{"level":2,"heading":"Escalation","markdown":"Ping the lead, then the PM within 10 minutes."}'

# Resolution (ACCEPT is the human court; DECLINE the assigned court; WITHDRAW the proposer)
opentrain manager playbook proposals resolve --job-id <job-id> \
  --proposal-id <proposal-id> --idempotency-key decline-escalation-v1 \
  --decision DECLINE --expected-proposal-revision 0 --note "Already covered in section 4"

# Publication (human job manager only)
opentrain manager playbook publish --job-id <job-id> \
  --idempotency-key publish-v6 --expected-playbook-version 5 \
  --document-json '{"type":"doc","content":[...]}' \
  --publication-note "Tightened escalation" \
  --accept-proposal-ids-json '["<proposal-id>"]'
```

`manager guide get` still returns the canonical typed projection alone (the Agent Guide without the Playbook). It is kept for existing clients; new work reads `manager agent-guide get`.

## MCP

| Tool                                              | Purpose                                                                                 |
| ------------------------------------------------- | --------------------------------------------------------------------------------------- |
| `opentrain_get_job_context_agent_guide`           | Read the composite Agent Guide as structured JSON plus Markdown.                        |
| `opentrain_get_job_context_playbook`              | Read the published Playbook head.                                                       |
| `opentrain_list_job_context_playbook_versions`    | Page the newest-first version history.                                                  |
| `opentrain_get_job_context_playbook_version`      | Read one exact version.                                                                 |
| `opentrain_get_job_context_playbook_delta`        | Read the exact section delta between two versions, including tombstones.                |
| `opentrain_submit_job_context_playbook_proposal`  | Submit a `SECTION_UPSERT`, `SECTION_REMOVE`, or `NOTE` proposal.                        |
| `opentrain_list_job_context_playbook_proposals`   | List proposals oldest first, with effective expiry and staleness against the head.      |
| `opentrain_resolve_job_context_playbook_proposal` | Accept, decline, or withdraw an exact proposal revision.                                |
| `opentrain_publish_job_context_playbook`          | Publish a version from the closed editor-subset document. Human job-manager court only. |

The server's initialize response teaches this loop to every connected agent. The guide is also readable as Markdown through the resource `opentrain://jobs/{jobId}/operations/agent-guide`. The older `opentrain://jobs/{jobId}/operations/guide` resource and the `opentrain_get_job_context_operating_guide` tool return the canonical projection only and remain for existing clients.

## SDK

```ts theme={null}
import { OpenTrainClient } from "@opentrain-ai/sdk";

const client = new OpenTrainClient({ apiToken: process.env.OPENTRAIN_API_TOKEN! });

const { guide, markdown } = await client.getJobOperationsAgentGuide(jobId);
const held = guide.playbook?.playbookVersion ?? 0;

// Later, when a covered response names recommendation.agent_guide_changed:
const { delta } = await client.getJobOperationsPlaybookDelta(jobId, {
  fromVersion: held,
  toVersion: 5,
});
// delta.added, delta.changed carry full sections; delta.removedSectionIds are tombstones.

await client.submitJobOperationsPlaybookProposal(jobId, {
  kind: "SECTION_UPSERT",
  dedupeKey: "escalation.update",
  basePlaybookVersion: 5,
  title: "Clarify the escalation window",
  sectionId: "escalation",
  proposedSection: {
    level: 2,
    heading: "Escalation",
    markdown: "Ping the lead, then the PM within 10 minutes.",
  },
});
```

Also available: `getJobOperationsPlaybook`, `listJobOperationsPlaybookVersions`, `getJobOperationsPlaybookVersion`, `listJobOperationsPlaybookProposals`, `resolveJobOperationsPlaybookProposal`, and `publishJobOperationsPlaybook`. Keyed mutations send the `Idempotency-Key` header for you. `getJobOperationsOperatingGuide` returns the canonical projection alone and is kept for existing clients.

## HTTP API

All paths are relative to `https://app.opentrain.ai/api/public/v1/job-operations/jobs/{jobId}`.

| Method | Path                                       | Purpose                                                                                                                                                                         |
| ------ | ------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `GET`  | `/agent-guide`                             | The composite Agent Guide: `guide` (typed projection, Playbook, open-proposal count, precedence, checksum) plus `markdown`.                                                     |
| `GET`  | `/playbook`                                | The published head, or the empty state when nothing is published.                                                                                                               |
| `GET`  | `/playbook/versions?limit=`                | Newest-first version summaries with per-version deltas. `limit` is 1 to 200.                                                                                                    |
| `GET`  | `/playbook/versions/{playbookVersion}`     | One exact version with its sections. `404` when it does not exist.                                                                                                              |
| `GET`  | `/playbook/delta?fromVersion=&toVersion=`  | Exact section delta: `added`, `changed`, `removedSectionIds`, `unchangedSectionIds`, `sectionOrder`. `fromVersion` 0 means everything is new; `toVersion` defaults to the head. |
| `GET`  | `/playbook/proposals?status=&kind=&limit=` | Oldest-first proposal listing with effective expiry and `staleAgainstHead`.                                                                                                     |
| `POST` | `/playbook/proposals`                      | Submit a proposal. Returns `outcome` of `SUBMITTED`, `REPLAYED`, or `DEDUPLICATED`. Requires `Idempotency-Key`.                                                                 |
| `POST` | `/playbook/proposals/{proposalId}/resolve` | `ACCEPT`, `DECLINE`, or `WITHDRAW` under `expectedProposalRevision`. Requires `Idempotency-Key`.                                                                                |
| `POST` | `/playbook/publish`                        | Publish a version from the closed editor-subset document under the `expectedPlaybookVersion` pin. Human job-manager court. Requires `Idempotency-Key`.                          |
| `GET`  | `/guide`                                   | The canonical typed projection alone. Kept for existing clients.                                                                                                                |

Mutations use the `Idempotency-Key` header. Replaying the same key with the same payload returns the original result with `replayed: true`; reusing a key for a different payload fails closed.

Publication body fields: `expectedPlaybookVersion` (the current head, `0` when none), optional `expectedContextRevision`, `document`, optional `publicationNote` (up to 2,000 characters), optional `acceptProposalIds` (up to 50 open proposal ids whose exact section content lands in this version), and optional `agentLabel` for an agent acting under a human token. Unchanged content is refused, and every response is the closed public version, never the editor document.

## Handle refusals

| Situation                                                          | What OpenTrain returns                                                         | What to do                                                          |
| ------------------------------------------------------------------ | ------------------------------------------------------------------------------ | ------------------------------------------------------------------- |
| `basePlaybookVersion` or `expectedPlaybookVersion` is not the head | A recoverable `409` carrying the current version.                              | Re-read the guide or delta, then resubmit against the current head. |
| A proposal was already resolved or expired                         | `409`.                                                                         | Read the proposal list; do not retry the resolution.                |
| The same `dedupeKey` already has a live open proposal              | `outcome: DEDUPLICATED` with that proposal.                                    | Treat it as your proposal; do not submit a duplicate.               |
| An agent account tries to publish or accept a section proposal     | A refusal with no existence disclosure.                                        | Ask a human job manager to publish from the **Agent Guide** tab.    |
| Accepted section content does not match what the version landed    | Validation error naming the mismatched section and hashes; nothing is written. | Publish the exact proposed content or decline the proposal.         |

## Related

<CardGroup cols={2}>
  <Card title="Agent Guide" href="/docs/developers/concepts/agent-guide" icon="book-open">
    The concept: precedence, sections and hashes, deltas and tombstones, and automatic sync.
  </Card>

  <Card title="Manage a live job" href="/docs/developers/guides/manage-live-jobs-with-shared-context" icon="arrows-rotate">
    The context-first triage, claim, recheck, action, and handoff loop the guide sits inside.
  </Card>

  <Card title="CLI: Shared Job Context" href="/docs/developers/cli/job-operations" icon="terminal">
    The complete `opentrain manager` command family.
  </Card>

  <Card title="MCP: Shared Job Context" href="/docs/developers/mcp/job-operations" icon="plug">
    Every shared-context tool and the automatic initialize protocol.
  </Card>
</CardGroup>
