Continuous Documentation

Continuous documentation means your docs go live with the release that ships the code they describe: not before it, when readers would find a feature that is not out yet, and not weeks after it, when someone remembers to publish. Docs pages are written and reviewed in Leed as usual. What changes is the moment they publish, which your own git-based release pipeline decides.

It rests on one idea. Every docs page carries a source id, the commit it was written against. When a release ships, a job in your CI sends Leed the commits that release contains, and Leed schedules every docs page stamped with one of them, together, in one publishing slot. Nobody has to remember which pages belong to which release, and nothing unreviewed goes out.

The Leed plugin for Claude sets all of this up with one command, /leed:docs-ci, run in your product’s repository on GitHub or GitLab.

How a release publishes its docs

sequenceDiagram
    autonumber
    participant Dev as Engineer or agent
    participant Repo as Your repository
    participant Leed as Leed
    participant CI as Your release pipeline
    Dev->>Repo: Merge the code change to the stamp branch
    Dev->>Leed: Edit the docs page, stamped with that branch's commit
    Note over Leed: The page waits in revision, reviewed as usual
    CI->>CI: Release ships (a push to main, or a tag)
    CI->>Leed: The release's commits, with the pipeline's OIDC token
    Leed->>Leed: Match pages stamped with those commits,<br/>check page type and review status
    Leed-->>CI: Matched, scheduled, and any page it could not take
    Note over Leed: The matched pages publish together in one slot

The pipeline proves who it is with the short-lived OpenID Connect (OIDC) token GitHub Actions and GitLab CI already mint for every job. There is no Leed secret to store in CI, rotate or leak. Scheduling the pages happens exactly as scheduling a whole set or a release at once describes: one commit, one build and one deployment for the whole release.

What you need

RequirementWhy
The Growth plan or aboveScheduling pages by source id is a Growth feature. Below it, /leed:docs-ci stops before writing anything.
The Content Publisher role, or AdministratorA trust grants publish access, so creating one takes the same access as publishing.
The Leed CLI, signed inTrusts are created with leed settings oidctrust create by a signed-in person. They are deliberately not available over MCP or to API keys, so the skill cannot run over MCP alone.
A GitHub or GitLab repositorygitlab.com and self-managed GitLab are both supported. The skill reads the repository’s settings with your existing gh or glab sign-in.
The Leed plugin for ClaudeSee Get Started with the Leed Plugin for Claude.

/leed:docs-ci never commits, pushes or merges. It writes the CI change and the agent instructions into your working tree, and you review and merge them through your normal flow.

What /leed:docs-ci sets up

Three pieces, in this order. Run again, the skill finds what is already there and changes nothing.

1. An OIDC trust in Leed

The trust tells Leed which pipeline may schedule pages, and which pages. It accepts tokens from your repository’s release pipeline only:

  • The repository is pinned by its numeric id (repository_id on GitHub, project_id on GitLab), never by its path, because a path can be renamed and claimed by someone else while an id is never reused.
  • The release is pinned too: the release branch (refs/heads/main with the leed-release environment on GitHub, main with ref_type: branch on GitLab), or for tag releases the leed-release environment and the tag claims. Leed refuses a trust that pins the repository alone.
  • Page types are chosen up front. Only pages of the trust’s types publish with a release. Beyond the docs, the skill asks about blog posts or release announcements, a changelog or release-notes type, and API reference, and includes only what you confirm.
  • A minimum review status sets the least-reviewed page a release may publish:
Minimum statusPublishes pages that areSuits
approved (suggested)ApprovedTeams who want a named approver in Leed before anything goes out
in_revisionIn revision or approvedTeams who want a page to have entered review
draftDraft, in revision or approvedDocs-as-code teams whose review happens in the code merge request

The skill shows the exact leed settings oidctrust create command as a dry run and creates the trust only after you agree. Its output is an audience, leed-cms:<trustId>, which goes into the CI file. The audience is not a secret.

On a GitHub tag release, protect the tags before the trust exists: restrict the leed-release environment to the release tags (Settings → Environments → leed-release → Deployment branches and tags), and restrict who can create matching tags with a tag ruleset. GitHub’s token has no protected-ref claim, so until both are set anyone with write access could push a tag the trust accepts. On GitLab, protect the release tags (Settings → Repository → Protected tags). The skill waits for you to confirm.

2. The release job in your CI

The job uses Leed’s published integration, referenced from its own public repository rather than copied into yours:

ForgeWhat is added
GitHubA workflow of its own, .github/workflows/leed-docs-release.yml, using the action leed-ai/schedule-release@v1. Your other workflows are not touched.
gitlab.comThe component gitlab.com/leed-ai-oss/schedule-release/schedule@1.1.0, added to your existing .gitlab-ci.yml with its rules. Every existing line keeps its bytes.
Self-managed GitLabThe component’s template from gitlab.com, included by URL, pinned to the 1.1.0 tag and checked with integrity (GitLab 17.9 or later). An instance that cannot reach gitlab.com mirrors the component and includes the mirror.

The first job is a dry run (dry-run: "true"): it reports what it would schedule and changes nothing. Without a fixed publish time, pages publish 15 minutes after the job starts, which leaves room for the whole release to be scheduled first. You can also ask for a manual job, for re-running a release’s docs by hand from a given commit.

3. The stamping rule

A release can only find a page stamped with one of its commits, so whoever edits the docs, usually your own coding agent, has to stamp with the right one. The skill appends a section, ## Documentation updates (Leed), to your repository’s CLAUDE.md, or to AGENTS.md if that is the file you use. It tells the agent to:

  • update docs after the change merges to the stamp branch, and stamp with that branch’s commit, never a feature-branch or pre-squash commit;
  • put a published page into revision before editing it, and pass the commit as the sourceId on every write;
  • never publish: the release job does that;
  • remember which page types ride with a release, and that any other type has to be published another way;
  • write only tracked suggestions on a page someone has commented on, and hand finished pages over for review in the Leed editor.

How agents write pages over MCP is in Authoring Pages Over MCP.

Branch models

A stamp has to survive into the release, and still be unreleased when it is written. So the stamp branch is the branch feature work merges into, and the release has to come later. /leed:docs-ci asks how your repository works and applies this table:

Your setupStamp withRelease triggerSupported?
Feature work into develop or staging, merged (not squashed) to mainThe commit on the integration branchA push to mainYes
Squash into main, release by tagThe commit on mainA tag push, from the previous tagYes
Squash into main, a release workflow pushes a release commitThe commit on mainThe release workflow completingGitHub only, and only when main is the default branch
Squash into main, deploy on every push——No: there is no gap between stamping and release. Release by tag, by a release commit, or through an integration branch instead
An integration branch squashed or rebased into main——No: every stamp is rewritten away. Promote with a merge commit or a fast-forward instead

When your setup is refused, the skill says why and what would make it work, and writes nothing.

Checking it before the first release

Before any release runs, the skill checks the trust and the stamps against a real page with a dry run of schedule_pages_by_source_id, which changes nothing: a stamped page must appear as matched. The dry run is free on every plan.

The first release’s job then shows:

  • matched: pages stamped with one of the release’s commits;
  • would schedule: the matched pages that pass the trust’s page types and minimum status;
  • a ✗ line for each matched page that would not be scheduled, with its reason: a page type outside the trust, a status below the floor, a missing required field, or an internal page, which is never published (Internal pages cannot be published);
  • unmatched commits, which is normal: most commits change code, not docs.

When a dry run lists the right pages, change dry-run: "true" to "false" and merge it. From then on every release schedules its docs. A page that is already published with the release’s commit, because it was stamped as current, is counted as already published and left alone.

Troubleshooting

SymptomLikely cause
401 OIDC token rejected on the first runThe token’s claims do not match the trust: the wrong audience, a mistyped repository or project id, a job run from a ref or environment the trust does not pin, or a job missing environment: leed-release. The message never says which, by design; the skill gives you a temporary step that prints the token’s named claims (never the token) to compare.
A 401 on GitHub after a rename, a transfer, or for a repository created after July 15, 2026GitHub changed the default sub claim’s format for those repositories. A trust that pinned sub breaks; one made by /leed:docs-ci pins the discrete claims and is unaffected. Replace a sub-pinned trust with one on the discrete claims.
No OIDC token available on GitHubThe workflow is missing permissions: id-token: write.
A 403The trust matched, but the request asked for more than it allows, such as a minimum status below the trust’s own.
A 402The plan does not include scheduling by source id (Growth and above).
A page did not publish, and the job is greenIts type is not one of the trust’s page types, its status is below the floor, or it is stamped with a commit that is not in the release, such as a feature-branch commit. Look for its ✗ line.
It worked, then every release failsThe trust was revoked (active: false in leed settings oidctrust list). A revoked trust cannot be restored: create a new one and put its audience in the CI file.

The plugin’s other skills are described in The Leed Plugin for Claude: Skills, and publishing a documentation set by hand in Publishing a Documentation Set.

ESC