Foundry logo Foundry

Editorial workflows for teams

Foundry uses its existing draft, in_review, scheduled, published, and archived states for team workflows. Assignments, review decisions, and revision comparisons are built into the admin API and default admin theme.

Enable approval enforcement

editorial:
  require_approval: true

This setting defaults to false, preserving existing publication workflows. Enable it before allowing a team to publish through the admin API. Direct edits to repository files, plugins with filesystem access, and configuration changes remain trusted operator actions; this is an admin workflow boundary.

With enforcement enabled, the saved revision must be approved by an independent reviewer before an editor publishes or schedules it. Approval is separate from publication: reviewers decide; editors publish. Existing published files remain published when the policy is enabled, but future publication actions require a current approval. Editing approved or published content clears its approval and returns it to draft. Restore also returns content to draft and requires fresh review.

Assign and review a document

  1. Save a draft, then open Team review in the document editor.
  2. An editor sets its Owner, Assignee, and Reviewer using active admin usernames. Empty Assignee or Reviewer clears that assignment; empty Owner preserves it.
  3. The owner or assigned author saves the content and selects Request Review, then saves the document to enter in_review.
  4. The reviewer loads that saved revision and selects Approve saved revision or Request changes, optionally adding a review comment.
  5. An editor selects Publish approved revision and saves, or sets a future Scheduled Publish time and the scheduled state.

Review controls act on saved content. Unsaved changes must be saved first. A stale revision is rejected instead of approving newer content inadvertently. The assigned reviewer is the only reviewer who may decide when one is specified; otherwise any reviewer can decide. The owner, assignee, and last content editor cannot approve or request changes on their own revision. A reviewer can read content and make decisions without permission to edit its body or publish it.

Ownership uses the existing document author field. Assignment grants an author access to the assigned document without changing its owner. Raw saves cannot transfer ownership or forge assignments, approvals, or review history. Use the assignment action instead. Changes to assignments clear approval; with enforced review, assignment changes to published or scheduled content return it to draft.

Editorial actions and status changes retain snapshots in the existing revision history. The document also records decision actor, time, revision, and comment under its server-managed editorial frontmatter. The editor displays recent review events; complete events remain in the document and retained revisions.

Capabilities

Role Editorial access
Author Read and edit owned or assigned documents; request review
Reviewer Read documents; approve or request changes
Editor Edit, assign ownership/reviewers, review others' revisions, and publish
Admin All capabilities; independent review is still required

Custom roles can use documents.assign, documents.review, and documents.publish. These supplement the existing document read/write and history capabilities; .own grants remain scoped to ownership or assignment.

Scheduling and revision comparison

A scheduled document becomes eligible for publication when its publish time arrives and is hidden again after its unpublish time. Static deployments need a build and deployment at those times; merely setting a timestamp does not launch a deployment job. Scheduled publication requires a future publish time, and an unpublish time must follow it.

The existing revision comparison now returns top-level frontmatter changes and a separate body diff in addition to the original raw comparison. This makes content changes easier to distinguish from workflow and metadata changes. Comparisons accept at most 1 MiB and 2,000 lines per revision to bound memory use.

Admin API and SDK

POST /__admin/api/documents/editorial (adjust for your configured admin prefix):

{
  "source_path": "posts/story.md",
  "action": "approve",
  "expected_revision": "revision hash from document.editorial.revision",
  "note": "Fact check complete"
}

Actions are assign, approve, and request_changes. Assignment additionally accepts owner, assignee, and reviewer. Include lock_token when required by your document access. Each request requires an authenticated admin identity.

GET /api/document exposes editorial, including assignments, approval, events, the current revision, and require_approval. The admin SDK exposes mutations as documents.editorial(input). Existing save, status, restore, and diff endpoints participate in the same policy; publishing raw frontmatter bypasses no checks.

POST /api/documents/diff additionally returns body_diff and frontmatter_changes (field, before, after). Its existing diff, left_raw, and right_raw fields remain available.