# Manage shared folder Instructions

Preview, migrate, activate, and maintain one shared instruction tree across the jobs in an employer folder.

Source: https://www.opentrain.ai/docs/developers/guides/manage-folder-instructions/

Folder Instructions are the same pages you edit in the employer workspace.
Eligible AI trainers read them from each child job's **Instructions** tab.
They are not a separate document store or a language-specific access boundary.

Use CLI or MCP **0.27.0 or later**, or TypeScript SDK **0.25.0 or later**.
Start with [CLI authentication](https://www.opentrain.ai/docs/developers/quickstart-cli/) or
[MCP setup](https://www.opentrain.ai/docs/developers/quickstart-mcp/). Your account needs current employer
access to the folder and its jobs, plus `instructions:read` and
`instructions:write` for this complete workflow. A read-only token can inspect
and preview migration, but cannot confirm or apply it. POST requests also
require a verified account.

## Find and inspect the target

Use your employer job inventory, not public marketplace search. Inspect a
known job and use its `placement.folder.id`:

```bash
opentrain jobs list
opentrain jobs get --job-id <job-id>
opentrain instructions folder inspect --folder <folder-id>
opentrain instructions folder inspect --folder <folder-id> --include-content
```

Job discovery requires the corresponding job-read permission. Folder inventory
lists every child job, direct and inherited pages, delivery mode, and current
worker-visible content. The default inventory is metadata-only; request
content explicitly when you need the documents. Neither read activates
folder Instructions or archives job pages.

## Prepare one reviewed change

Use `ACTIVATE` for a folder without active Instructions, or `APPEND` to add
pages to an existing shared guide. Save the request as `folder-change.json`:

```json
{
  "kind": "ACTIVATE",
  "idempotencyKey": "shared-guide-2026-01",
  "sources": [
    {
      "jobId": "english-job-id",
      "pageIds": ["workflow-page-id"],
      "label": "English",
      "groupFlatPages": true
    },
    {
      "jobId": "japanese-job-id",
      "pageIds": "ALL",
      "label": "Japanese"
    }
  ],
  "newPages": [
    {
      "ref": "start-here",
      "parentRef": null,
      "title": "Start here — shared workflow",
      "icon": null,
      "contentSchemaVersion": 1,
      "content": {
        "type": "doc",
        "content": [
          {
            "type": "paragraph",
            "attrs": { "id": "shared-workflow-introduction" },
            "content": [
              {
                "type": "text",
                "text": "Read the shared workflow, then the instructions labeled for your assigned language."
              }
            ]
          }
        ]
      }
    }
  ]
}
```

Replace the example IDs and text with your reviewed content. Do not activate
an incomplete guide in place of necessary project rules.

```bash
opentrain instructions folder preview --folder <folder-id> \
  --request folder-change.json > folder-preview.json
```

Execution returns one JSON envelope. Read `data.canApply`, `data.findings`,
the complete mapping and `data.planDigest`. A successful preview command can
still describe a **blocked** plan with `canApply: false`.

Review every affected job, not just selected sources. First activation archives
all active child-job pages together with activating the destination. Unselected
pages become hidden from AI trainers, but their originals are retained. The
preview names hidden content, the before/after worker view, exact labels and
order, and link/media outcomes. Copies and new pages become visible together;
there is no temporary empty guide.

All eligible AI trainers on child jobs can read shared copies. This expands
the audience of language-specific or job-specific source material. A title
such as “Japanese” labels guidance; it does not restrict readers.

### Selection and hierarchy

- `pageIds: "ALL"` selects active roots and their children. An empty job is
  valid and contributes no pages.
- Explicit page IDs select the reviewed content. Add `includeArchived: true`
  only to recover retained archived sources that are still readable.
- Duplicate titles remain separate pages. Nothing is silently deduplicated.
- `groupFlatPages: true` groups flat source pages under a labeled root. Existing
  root/subpage trees retain their two-level structure; they cannot be wrapped
  into an unsupported third level.
- To copy an individual child without its parent, explicitly include its ID in
  `promoteToRootPageIds`. Review the resulting root label and order.
- `parentRef` refers to another new page's `ref`. Only a root and one subpage
  level are supported.

Unavailable source content, unsafe internal links, unsupported hierarchy,
unrecoverable media, cross-organization sources or oversized inventories block
the applicable plan. Nothing is silently omitted to make a plan fit.

## Confirm, drain, then apply

Confirm the unchanged request with the digest you reviewed:

```bash
opentrain instructions folder confirm --folder <folder-id> \
  --request folder-change.json --plan-digest <reviewed-plan-digest> --confirm
opentrain instructions folder status --folder <folder-id> --operation <operation-id>
```

Save the returned operation ID. Confirmation freezes affected writers while
already-issued collaboration grants expire; it does **not** switch visible
Instructions. Wait until `quiesceReadyAt`, then apply:

```bash
opentrain instructions folder apply --folder <folder-id> \
  --operation <operation-id> --confirm
```

Only `state: "VERIFIED_READBACK"` with `readbackVerified: true` proves the
operation's canonical readback completed. `COMMITTED` or `READBACK_PENDING`
does not authorize creating another operation. Inspect and retry the same
operation ID. Do not bypass the drain or change keys after a timeout.

Changed source documents or membership require a fresh reviewed plan. Status
is read-only and never renews an expired lease. An expired, uncommitted
operation may require explicit `resume`; inspect its result before applying.

```bash
opentrain instructions folder resume --folder <folder-id> \
  --operation <operation-id> --confirm
opentrain instructions folder cancel --folder <folder-id> \
  --operation <operation-id> --confirm
```

Cancellation is for an uncommitted operation. It leaves existing visible
Instructions unchanged and preserves recovery content.

## Maintain the shared pages

After activation, use the existing authoring commands with `--folder` instead
of `--job`. Never supply both selectors:

```bash
opentrain instructions pages list --folder <folder-id>
opentrain instructions page get --folder <folder-id> --page <page-id>
opentrain instructions page create --folder <folder-id> --title "Review checklist" \
  --content-file checklist.tiptap.json --key review-checklist-v1
opentrain instructions checkout --folder <folder-id> --dir ./shared-instructions
opentrain instructions plan --dir ./shared-instructions --out ./shared-plan.json
opentrain instructions verify --folder <folder-id>
```

The create example is a no-write preflight. Review it before adding
`--confirm-live`. Use a current checksum for document patch/replacement.
Scope-bound bundles carry their folder identity; do not relabel a job bundle
as a folder bundle. DOCX import, images, supported video workflows, page links,
history/checkpoints/restore, schema upgrades and tree editing use the same
folder selector. Consult [CLI Instructions](https://www.opentrain.ai/docs/developers/cli/instructions/) for
the corresponding operation's flags.

Ordinary page creation cannot perform first activation. Use the reviewed
folder-change workflow above. Archiving the last shared page does not restore
archived job pages: inspect what remains visible before confirming.

The employer editor can edit these same pages. Recheck them from two eligible
child jobs after a material change, including asset rendering. Semantic
`verify` and a visual-review checklist are not proof that a real browser or
an already-open collaborative session received the change.

## Recover or reverse

Authorized employers can export preserved originals:

```bash
opentrain instructions folder recovery --folder <folder-id> \
  --operation <operation-id> > originals.json
```

To reverse, preview a new request containing `kind: "REVERSE"`, the original
`operationId`, and a new stable `idempotencyKey`. Confirm and apply that new
reviewed plan using the same lifecycle. Reversal refuses newer content, tree,
schema or membership drift. It restores only the source pages that the
original operation archived; previously archived pages stay archived.

Old migrated links resolve to a current mapped destination only while the
reader still has the required source-job and destination access. Removing a
job from the folder or revoking its contract does not preserve a stale grant.
Unmapped archived links show an unavailable notice, not superseded guidance.

## Compatibility and retry limits

Existing `--job` clients keep their job scope. Folder writes require `LIVE`
delivery for the folder and every child job. `PUBLISHED` or `UNKNOWN` mode
refuses with `INSTRUCTIONS_RELEASE_MODE_UNSUPPORTED`; inspect its limitations.
This workflow does not enable releases, acknowledgments or Read Required
notifications.

Migration requests are capped at 4 MiB; complete inventory and plan budgets
are each 16 MiB, with at most 500 jobs, 500 retained/resulting pages and 2,000
media references. Content and recovery checks can impose tighter limits.
Oversized operations refuse instead of returning a partially applicable plan.

Authoring has operation-specific recovery. Discovery exposes
`folder-instruction-authoring-retry/1`; it is not a promise of automatic retry:

- Receipt-backed create/tree/history/upload operations reuse the identical key
  and payload. One-time upload grants are not replayed.
- Patch/replace/metadata/archive require inspection of the same page and tree;
  obtain a fresh preflight on drift. A missing page is not proof of archive.
- Schema upgrades require current page and intent identity/revision/status.
  Pending is progress, not completion; failed/expired intents need a new request.
- Video cancellation inspects the same asset. `CANCELING` requires polling;
  `READY` is immutable, and missing/uncertain state is not cancellation success.

See the [folder API and SDK reference](https://www.opentrain.ai/docs/developers/api-reference/instructions/folders/)
and [MCP Instructions](https://www.opentrain.ai/docs/developers/mcp/instructions/) for the same workflow
without the CLI.
