Skip to content
OpenTrain AIOpenTrain AIOpenTrain AIDocs

Ask OpenTrain

Answers from the documentation, with sources.

What would you like to do with OpenTrain?

AI answers can be mistaken. Check the linked sources. Don’t include private account information.

Open app

DEVELOPER DOCUMENTATION

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 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.

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.

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.

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.

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.

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.

Acknowledge only what you received

Checkpoint the revision the envelope actually delivered to you. Never acknowledge a revision you have not received.

Terminal window
# 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.

ToolPurpose
opentrain_get_job_context_agent_guideRead the composite Agent Guide as structured JSON plus Markdown.
opentrain_get_job_context_playbookRead the published Playbook head.
opentrain_list_job_context_playbook_versionsPage the newest-first version history.
opentrain_get_job_context_playbook_versionRead one exact version.
opentrain_get_job_context_playbook_deltaRead the exact section delta between two versions, including tombstones.
opentrain_submit_job_context_playbook_proposalSubmit a SECTION_UPSERT, SECTION_REMOVE, or NOTE proposal.
opentrain_list_job_context_playbook_proposalsList proposals oldest first, with effective expiry and staleness against the head.
opentrain_resolve_job_context_playbook_proposalAccept, decline, or withdraw an exact proposal revision.
opentrain_publish_job_context_playbookPublish 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.

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.

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

MethodPathPurpose
GET/agent-guideThe composite Agent Guide: guide (typed projection, Playbook, open-proposal count, precedence, checksum) plus markdown.
GET/playbookThe 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/proposalsSubmit a proposal. Returns outcome of SUBMITTED, REPLAYED, or DEDUPLICATED. Requires Idempotency-Key.
POST/playbook/proposals/{proposalId}/resolveACCEPT, DECLINE, or WITHDRAW under expectedProposalRevision. Requires Idempotency-Key.
POST/playbook/publishPublish a version from the closed editor-subset document under the expectedPlaybookVersion pin. Human job-manager court. Requires Idempotency-Key.
GET/guideThe 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.

SituationWhat OpenTrain returnsWhat to do
basePlaybookVersion or expectedPlaybookVersion is not the headA recoverable 409 carrying the current version.Re-read the guide or delta, then resubmit against the current head.
A proposal was already resolved or expired409.Read the proposal list; do not retry the resolution.
The same dedupeKey already has a live open proposaloutcome: DEDUPLICATED with that proposal.Treat it as your proposal; do not submit a duplicate.
An agent account tries to publish or accept a section proposalA 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 landedValidation error naming the mismatched section and hashes; nothing is written.Publish the exact proposed content or decline the proposal.