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

CLI: Shared Job Context

Use opentrain manager commands to enter a live job with shared state, coordinate work safely, and leave a durable handoff.

opentrain manager is the context-first command tree for managing an existing employer job. Root and manager help teach the operating protocol automatically, so a new agent session does not need a copied prompt or local memory file.

Terminal window
npm install -g @opentrain-ai/cli@0.26.0
opentrain manager help

Every command supports --json. Reads require jobs:read; mutations require jobs:write and canonical access to the exact job.

Terminal window
opentrain manager context get --job-id <job-id> --json
opentrain manager context delta --job-id <job-id> --since-revision 1842 --json
opentrain manager person get --job-id <job-id> --person-user-id <user-id> --json
opentrain manager sweep --job-id <job-id> \
--expected-context-revision 1842 \
--idempotency-key sweep-job-session-page-1 \
--body-json '{"limit":100}'

Start with context get before deciding or acting. In a writable session, run sweep with that revision. If it returns hasMore: true, run the next page with the response’s contextRevision and a new stable page key. When hasMore is false, fetch context again. A read-only session does not sweep. Continue a delta with nextRevision until its hasMore is false.

The compact context response includes a bounded top-priority attention block, evaluator-health metadata, effective-policy summary, current claim ownership, and an Agent Guide digest. Use the dedicated reads when you need the full signal, policy, or guide payload:

Terminal window
opentrain manager signals list --job-id <job-id> --json
opentrain manager policies effective --job-id <job-id> --json
opentrain manager agent-guide get --job-id <job-id> --format markdown

Only active, fresh signals from active rules appear in the default priority feed. Incomplete or stale evaluator runs remain visible in context health; do not treat their findings as current actionable work.

CLI 0.11.0 automatically carries one private server-issued session credential and the latest per-job delivery token across every covered command. You do not copy those values into flags or prompts.

Each covered JSON response includes sync and syncCoverage. Inspect sync.conflicts, sync.recommendations, sync.nextOperations, and sync.resyncRequired before the next write. syncCoverage.coverage is one of:

  • native for a Job Operations command;
  • bridged for a job-resolvable messaging or LMS command; or
  • none with the reason that the operation did not refresh context.

For durable continuity, set a stable agent identity in the runtime:

Terminal window
export OPENTRAIN_AGENT_INSTANCE="project-manager-west"
opentrain manager context get --job-id <job-id> --json

Paseo supplies PASEO_AGENT_ID automatically. If neither variable exists, the CLI deliberately remains ephemeral instead of sharing one agent’s private state through a working directory. State is stored with private permissions under ${XDG_STATE_HOME:-~/.local/state}/opentrain/job-ops-sync. Deleting it only causes the next covered call to bootstrap from canonical OpenTrain state.

Wait for a new shared-context delivery without rescanning every subsystem:

Terminal window
opentrain manager sync poll --job-id <job-id> --wait-seconds 25 --json
opentrain manager sync poll --job-id <job-id> --watch --max-polls 20 --json

Watch mode is bounded and emits one JSON line per poll. A sync delivery helps the agent choose what to inspect; re-read the affected canonical record before acting.

You do not need to tell the agent to create an operating brief or discover the setup commands. While required setup is missing, every covered response carries recommendation.job_setup_incomplete, and the automatic next-operation list leads the agent to manager setup.

Terminal window
opentrain manager setup status --job-id <job-id> --json
opentrain manager setup help

The staged flow is status → declare setup.* intent → plan → human review → apply --confirm-live → verify, resolve, and hand off. Only the agent whose current durable session matches the declaring intent may present or apply the plan. A DUPLICATE result names the existing winner but does not transfer ownership, and a copied plan cannot be applied from another session.

plan is zero-write and never guesses an unresolved decision. apply rechecks the shared revision, setup evidence, and same-session ownership before sending the exact approved canonical writes.

See Set Up Shared Job Operations for the full command sequence and safe deferral behavior.

Let the CLI teach this job’s atomic work

Section titled “Let the CLI teach this job’s atomic work”

The CLI does not ship predefined business work types. Every covered response includes sync.workCatalog and automatically recommends Work Catalog setup when this job has no active definitions, recurring provisional work needs a definition, or an inferred definition awaits human approval. The employer does not need to discover this feature or ask the agent to configure it.

Start with the synchronized recommendations and inspect the current catalog:

Terminal window
opentrain manager work definitions list --job-id <job-id> --json
opentrain manager work definitions get --job-id <job-id> \
--definition-key <job-defined-key> --json
opentrain manager work executions list --job-id <job-id> \
--status OPEN --json

One durable agent session wins the ops:work-catalog-setup intent. The winner observes real work, begins immediate ad hoc work as a provisional execution, and proposes a recurring definition from evidence. Another session that sees the existing setup owner stands down.

Terminal window
opentrain manager work executions begin-provisional --help
opentrain manager work definitions propose-from-provisional --help
opentrain manager work definitions append-version --help
opentrain manager work definitions activate --help

Each mutation has focused help and --print-schema; use those generated schemas instead of inventing request fields. An INFERRED definition stays inactive until a non-agent job manager explicitly approves its exact content and coordination digests. Every execution mints one coordinating action. Claim that action before working; it is the single shared ownership authority.

Terminal window
opentrain manager work executions begin --help
opentrain manager actions claim --help
opentrain manager actions renew --help
opentrain manager actions handoff --help

The human-only WORK_COORDINATION_MODE policy determines whether the catalog is advisory (OPEN), required for guarded work with provisional definitions allowed (COORDINATED), or required with an active approved definition (MANAGED). If managers disagree about the workflow, preserve the current mode and definition, then use a shared proposal for review instead of silently overwriting it.

See Dynamic Work Catalog for the definition lifecycle, setup lease, version bindings, external attestations, and conflict behavior.

Read the Agent Guide and propose Playbook changes

Section titled “Read the Agent Guide and propose Playbook changes”

A new or resumed session’s sync.nextOperations ends with job_operations.agent_guide.get. Read the guide once; afterwards run the delta only when a covered response carries recommendation.agent_guide_changed naming the exact fromVersion and toVersion.

Terminal window
opentrain manager agent-guide get --job-id <job-id> --format markdown
opentrain manager playbook delta --job-id <job-id> --from-version 3 --to-version 5
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."}'

Proposals are recommendations, never enforced. --base-playbook-version must equal the current published head, and a live open proposal under the same --dedupe-key returns DEDUPLICATED instead of a duplicate. Publishing (manager playbook publish) is a human job-manager act; an agent account is refused. manager guide get still returns the canonical projection alone for existing clients. See Follow and Improve the Agent Guide for every command, flag, and refusal.

Terminal window
opentrain manager signals get --job-id <job-id> --signal-id <signal-id> --json
opentrain manager signals claim --job-id <job-id> --signal-id <signal-id> \
--expected-context-revision 1843 \
--expected-signal-revision 2 \
--idempotency-key investigate-lms-cohort-v1 \
--actor-agent-label claude-code:run-7 --lease-seconds 900

Signal claim is the only operation that turns a deterministic finding into owned work. It atomically creates or reuses the linked coordination action and acquires its lease. Re-read the canonical evidence before deciding what the signal means: a repeated LMS failure can indicate unclear instructions, a difficult question, an assignment problem, or a real knowledge gap.

The signal must be active and fresh, with effective triage OPEN or ACKNOWLEDGED. The CLI rejects stale, incomplete, live-snoozed, dismissed, and shadow-rule signals instead of creating duplicate or premature work.

Acknowledging, snoozing, or dismissing is triage, not ownership:

Terminal window
opentrain manager signals acknowledge --job-id <job-id> --signal-id <signal-id> \
--expected-context-revision 1844 --expected-signal-revision 2 \
--idempotency-key acknowledge-lms-cohort-v1 \
--reason 'Reviewed; awaiting updated source data'
opentrain manager signals snooze --job-id <job-id> --signal-id <signal-id> \
--expected-context-revision 1844 --expected-signal-revision 2 \
--idempotency-key snooze-lms-cohort-v1 \
--snooze-until 2026-08-29T16:00:00Z \
--reason 'Internal grader is completing the review'
opentrain manager signals dismiss --job-id <job-id> --signal-id <signal-id> \
--expected-context-revision 1844 --expected-signal-revision 2 \
--idempotency-key dismiss-lms-cohort-v1 \
--reason 'Canonical records confirm this occurrence is no longer relevant'

Only the deterministic evaluator clears the underlying condition. If evidence changes materially or the condition recurs, OpenTrain can reopen it as new work.

Terminal window
opentrain manager actions list --job-id <job-id> --status OPEN --json
opentrain manager actions create --job-id <job-id> \
--expected-context-revision 1843 \
--idempotency-key grade-joshua-attempt-3-create \
--body-json '{"title":"Grade Joshua attempt 3","priority":"HIGH","subjectPersonUserId":"<user-id>"}'
opentrain manager actions claim --job-id <job-id> --action-id <action-id> \
--expected-context-revision 1844 \
--idempotency-key grade-joshua-attempt-3-claim \
--body-json '{"expectedActionRevision":0,"leaseSeconds":900,"actorAgentLabel":"claude-code:run-7"}'
opentrain manager actions complete --job-id <job-id> --action-id <action-id> \
--expected-context-revision 1845 \
--idempotency-key grade-joshua-attempt-3-complete \
--body-json '{"expectedActionRevision":1,"claimReceipt":"<exact-claim-receipt>","outcome":"Attempt 3 graded and canonical result verified"}'

Use actions release if you stop without completing the work. actions cancel closes obsolete work with an audited reason. A claim fails if its dependencies are incomplete or another unexpired claimant owns it.

The revision numbers above are illustrative. Re-read context after every mutation; never increment a revision locally. --body-json and --body-file contain only operation-specific fields—keep the job ID, expected context revision, and idempotency key in their dedicated flags.

Immediately before an outbound message or consequential canonical write, re-read the affected OpenTrain record and latest authorized conversation/thread. Shared context tells you what to inspect; it is not a replacement for that final check.

Coordinate spontaneous work and disagreements

Section titled “Coordinate spontaneous work and disagreements”

Declare an intent before starting work that has no shared action yet:

Terminal window
opentrain manager intents declare --job-id <job-id> \
--idempotency-key investigate-feather-access-v1 \
--kind OTHER --intent-key feather-access:<user-id> \
--title "Investigate Feather access" \
--expected-context-revision 1845 --lease-seconds 900
opentrain manager intents list --job-id <job-id> --status ACTIVE --json
opentrain manager intents resolve --job-id <job-id> --intent-id <intent-id> \
--idempotency-key investigate-feather-access-resolve-v1 \
--resolution COMPLETED --expected-intent-revision 1

An overlapping declaration returns the live winner so another agent can avoid duplicate work.

If a project manager wants to change the current workflow, record a non-enforced proposal instead of silently following a competing local plan:

Terminal window
opentrain manager proposals submit --job-id <job-id> \
--idempotency-key training-gate-proposal-v1 \
--kind POLICY --dedupe-key training-production-gate \
--title "Move to completion-only training gate" \
--body "Use course completion instead of scored review."
opentrain manager proposals list --job-id <job-id> --status OPEN --json

Use proposals review or proposals withdraw with the returned exact revision. Accepting a proposal links separately authorized canonical work; it does not execute the policy, message, or assignment.

Keep flexible guidance at the right scope:

Terminal window
opentrain manager overlays get --job-id <job-id> --json
opentrain manager overlays set --job-id <job-id> \
--idempotency-key personal-finance-review-v1 \
--layer PERSONAL --expected-overlay-revision 0 \
--entries-json '[{"kind":"NOTE","statement":"Group blockers by lane"}]'

TEAM guidance is owner-controlled and shared. PERSONAL belongs to one manager. SESSION is one connection’s scratch context. Overlays are attributed guidance only; they cannot change readiness, gates, or effective policies.

For a managed message, use the fail-closed alias and include every guard field:

Terminal window
opentrain manager messages send --contract-id <contract-id> \
--content-file ./message.txt \
--idempotency-key worker-reminder-2026-08-28 \
--job-operations-job-id <job-id> \
--job-operations-expected-context-revision 1845 \
--job-operations-action-id <action-id> \
--job-operations-expected-action-revision 1 \
--job-operations-claim-receipt '<exact-claim-receipt>' \
--job-operations-expected-latest-message-id <message-id>

Use --job-operations-expected-latest-message-id none only when the authorized conversation was observed empty. The alias refuses to make a network request when any guard field is missing. The idempotency key must be 8–128 characters using letters, numbers, ., _, :, or -. This exact path requires both messages:write and messages:manage, resolves either an authorized Job Message or Proposal Message to its canonical job, and commits the message and context advance atomically. Ordinary opentrain messages send is intentionally unsynchronized and should not be used for claimed shared-job work.

Terminal window
opentrain manager brief publish --job-id <job-id> \
--expected-context-revision 1846 --idempotency-key brief-revision-7 \
--body-file ./brief.json
opentrain manager decisions list --job-id <job-id> --json
opentrain manager decisions record --job-id <job-id> \
--expected-context-revision 1847 --idempotency-key manual-pass-kevin-v1 \
--body-file ./decision.json
opentrain manager observations list --job-id <job-id> \
--subject-person-user-id <user-id> --json
opentrain manager observations record --job-id <job-id> \
--expected-context-revision 1848 --idempotency-key slack-readback-2026-08-28 \
--body-file ./observation.json
opentrain manager checkpoint --job-id <job-id> \
--expected-context-revision 1849 --idempotency-key checkpoint-session-7 \
--body-json '{"acknowledgedRevision":1849,"actorAgentLabel":"claude-code:run-7"}'
opentrain manager handoff --job-id <job-id> \
--expected-context-revision 1849 --idempotency-key handoff-session-7 \
--body-file ./handoff.json

Briefs define the current objective and typed readiness workflow. Decisions preserve policies, manual judgments, and approved exceptions. List decisions and observations when historical rationale or supersession affects the work; the compact context is the current projection, not the complete history. Observations are only for typed external evidence, inference, or recommendations—never copy ordinary proposal, contract, identity, assessment, To-do, training, message, payment, or provider facts into an observation.

For state OpenTrain cannot read directly, an OBSERVED observation may carry a strict top-level externalAttestation. Use ATTEST with a required bounded expiry, or INVALIDATE to retire a named attestation. Pass agent attribution through the top-level actorAgentLabel; the nested metadata key is reserved. Read manager agent-guide get (its canonical projection carries externalCoverage) and rely only on entries reported as current.

Use the typed policy commands when a rule governs job-wide workflow or agent behavior:

Terminal window
opentrain manager policies list --job-id <job-id> --json
opentrain manager policies record --job-id <job-id> \
--expected-context-revision 1850 \
--idempotency-key training-gate-completion-v2 \
--body-file ./typed-policy.json
opentrain manager policies verify-enforcement --job-id <job-id> \
--expected-context-revision 1851 \
--idempotency-key verify-training-gate-v2 \
--body-file ./policy-enforcement.json

A policy record identifies its human approver, recording user, recording agent, enforcement target, and the exact active policy decision it supersedes. GUIDE with status APPLIED means the rule was published in the shared guide; it does not mean a runtime subsystem enforces it. The TRAINING_PRODUCTION_GATE v1 payload accepts only schemaVersion and basis. Use an attributed OPERATING_RULE.first-production-task-limit guide policy for a one-task-then-stop instruction.

After a policy change, fetch context and manager agent-guide get again and verify the new context revision and guide checksum. The Agent Guide is the shared AGENTS.md-equivalent for the job, but canonical records and effective typed policies remain authoritative; the published Playbook is guidance beneath them.

If a command returns a stale context or action revision:

  1. Run manager context get again.
  2. Re-read the affected canonical resource.
  3. Decide whether the intended action is still correct.
  4. Retry only with the new revision and a key that represents that deliberate intent.

Do not substitute --force or blind retries for reconciliation. See the HTTP reference and live-job guide.