documenteer.toml reference#

Rubin’s Sphinx user guide configuration with documenteer.conf.guide uses a documenteer.toml file, located next to the Sphinx conf.py file to configure metadata about the project. This page describes the schema for this documenteer.toml file. For a step-by-step guide, see Setting up the Documenteer configuration for Rubin user guides.

[project] table#

The [project] table is where most of the project’s metadata is set.

Required

title#

Required

Name of the project, used as titles throughout the documentation site. The title can be different from the package name, if that’s the local standard.

[project]
title = "Documenteer"

base_url#

Optional Auto set by project.python

The root URL of the documentation project, used to set the canonical URL link rel, which is valuable for search engines.

[project]
base_url = "https://documenteer.lsst.io"

github_url#

Optional Auto set by project.python

The URL for the project’s GitHub source repository. When set, a link to the repository is included in the site’s header.

[project]
github_url = "https://github.com/lsst-sqre/documenteer"

github_default_branch#

Optional

The default branch on GitHub. Default is main. Used in conjunction with the “Edit on GitHub” link, see sphinx.show_github_edit_link.

version#

Optional Auto set by project.python

The project’s version, which is set to the standard Sphinx version and release configuration variables.

[project.openapi]#

Optional

Web applications that use OpenAPI can include a [project.openapi] table in documenteer.toml to embed a Redoc subsite of the API documentation (see Embedding a Redoc subsite for OpenAPI (HTTP API) documentation).

doc_path#

Optional

The docname (without extension) of the page in the Sphinx documentation tree where the Redoc HTML page is built. Default is api.

openapi_path#

Optional

The path to the OpenAPI specification file, relative to the Sphinx configuration file, conf.py. If [project.openapi.generator] is set, this is the path where the OpenAPI specification file is generated.

[project.openapi.generator]#

Optional

If this table is provided, the OpenAPI specification file is generated from a user-specified Python function. This is useful for FastAPI and similar applications where the OpenAPI specification is generated from the application code.

function#

Required

The Python function that generates the OpenAPI specification file. This function must return the OpenAPI specification as a JSON-serialized string.

Specify the function as <module>:<function>. For example, if the function called create_openapi is in the main.py module of the example package, the value would be "example.main:create_openapi".

[project.openapi.generator]
function = "example.main:create_openapi"

positional_args#

Optional

Positional arguments to pass to the function, if required.

[project.openapi.generator]
function = "example.main:create_openapi"
positional_args = ["arg1", "arg2"]

keyword_args#

Optional

Keyword arguments to pass to the function, if required.

[project.openapi.generator]
function = "example.main:create_openapi"
keyword_args = {kwarg1 = "value1", kwarg2 = "value2"}

[project.python]#

Optional

Projects that use a pyproject.toml to set their build metadata can include a [project.python] table in documenteer.toml. With this, many metadata values are automatically detected — look for Auto set by project.python badges above.

Note

If a value is directly set, such as version, that value will override will override information discovered from the Python project itself.

package#

Required

This is the Python project’s name, as set in the name field of the [project] table in pyproject.toml. Note that the package name can be different from the Python module name. Setting this field actives automatic metadata discovery for Python projects.

[project]

[project.python]
package = "documenteer"

documentation_url_key#

Optional

By default the base_url is detected from the Homepage field in the [project.urls] table of pyproject.toml. If your documentation’s URL is associated with a different field label, set that with documentation_url_key.

github_url_key#

Optional

By default the github_url is detected from the Source field in the [project.urls] table of pyproject.toml. If your GitHub repository’s URL is associated with a different field label, set that with github_url_key.

[sphinx]#

Optional

This [sphinx] table allows you to set a number of Sphinx configurations that you would normally set through the conf.py file.

disable_primary_sidebars#

Optional

On some pages the default sidebar (on the left) is inappropriate, such as index pages that already contain a table of contents as their main content. In that case, you can set individual pages or globs (without extensions) of pages that are shown without the primary sidebar. The default is ["index"] to remove the sidebar from the homepage.

[sphinx]
disable_primary_sidebars = [
  "**/index",
  "changelog"
]

Note

This configuration is for the primary sidebar, on the left side, containing side or section-level navigation links. To remove the page-level contents sidebar, on the right side, add :html_theme.sidebar_secondary.remove: to the page’s file metadata.

exclude#

Optional

A list of file paths, relative to conf.py, to exclude from the Sphinx build. This configuration is often used to prevent file unrelated to the documentation from being accidentally included in the site build. documenteer.conf.guide includes common files and directories, so you may not need to modify this configuration in standard situations.

extensions#

Optional

A list of Sphinx extensions to append to the extensions included in the Documenteer configuration preset (see documenteer.conf.guide). Duplicate extensions are ignored.

Remember that additional packages may need to be added to your project’s Python dependencies (such as in a requirements.txt or pyproject.toml file).

nitpicky#

Optional

Set to true to escalate Sphinx warnings to errors, which is useful for leveraging CI to notify you of any syntax errors. The default is false.

[sphinx]
nitpicky = true

See nitpick_ignore and nitpick_ignore_regex for ways to suppress unavoidable errors.

nitpick_ignore#

Optional

A list of Sphinx warnings to ignore. Each item is a tuple of two items:

  1. type, often the reStructuredText role or directive creating the error/warning.

  2. target, often the argument to the reStructuredText role.

[sphinx]
nitpick_ignore = [
  ["py:class", "fastapi.applications.FastAPI"],
  ["py:class", "httpx.AsyncClient"],
  ["py:class", "pydantic.main.BaseModel"],
]

This configuration extends the Sphinx nitpick_ignore configuration.

nitpick_ignore_regex#

Optional

A list of Sphinx warnings to ignore, formatted as regular expressions. Each item is a tuple of two items:

  1. type, a regular expression of the warning type.

  2. target, a regular expression of the warning target.

[sphinx]
nitpick_ignore_regex = [
  ['py:.*', 'fastapi.*'],
  ['py:.*', 'httpx.*'],
  ['py:.*', 'pydantic*'],
]

Tip

Use single quotes for literal strings in TOML.

This configuration extends the Sphinx nitpick_ignore_regex configuration.

rst_epilog_file#

Optional

Set this as a path to a reStructuredText file (relative to documenteer.toml and conf.py) containing substitutions and link targets that are available to all documentation pages. This configuration sets Sphinx’s rst_epilog configuration. If set, the file is also included in the Sphinx source ignore list to prevent it from becoming a standalone page.

documenteer.toml#
 [sphinx]
 rst_epilog_file = "_rst_epilog.rst"
_rst_epilog.rst#
.. _Astropy Project: https://www.astropy.org

.. |required| replace:: :bdg-primary-line:`Required`
.. |optional| replace:: :bdg-secondary-line:`Optional`

See Using the rst epilog for common links and substitutions.

python_api_dir#

Optional

Set this to the directory where Python API documentation is generated, through automodapi. The default value is api, which is a good standard for Python projects with a public API.

If the Python API is oriented towards contributors, such as in an application or service, you can change the default:

documenteer.toml#
[sphinx]
python_api_dir = "dev/api/contents"

[sphinx.redirects]#

Optional

A table of paths to redirect to other paths. Use this setting to redirect old page locations to the new locations when a documentation site is reorganized.

documenteer.toml#
[sphinx.redirects]
"old/path" = "new/path"
"old/path2" = "new/path2"

[sphinx.theme]#

Optional

Configurations related to the Sphinx HTML theme.

show_last_updated#

Optional

Default is true, so that each page shows a “Last updated on <date>.” timestamp at the bottom of each page.

See also

“Last updated” page timestamps for how the date is computed and the extension’s Sphinx configuration values.

The date is computed from the page’s Git commit history, not the filesystem modification time (which is meaningless in CI). It is the most recent commit date across the page’s own source file and any files the page pulls in with include or literalinclude directives, so editing an included snippet updates every page that uses it. Because the date is the last commit date, uncommitted local edits don’t change it; a page whose source has never been committed shows no timestamp.

Set this to false to hide the timestamp:

documenteer.toml#
[sphinx.theme]
show_last_updated = false

Important

Because the date comes from the Git history, your CI build must check out the full commit history. With actions/checkout, set fetch-depth: 0:

.github/workflows/ci.yaml#
- uses: actions/checkout@v6
  with:
    fetch-depth: 0

A shallow clone (the default) only fetches the most recent commit, so every page would otherwise report the same, incorrect date. To avoid publishing misleading data, Documenteer detects a shallow clone, omits the “Last updated” timestamp from every page, and emits a single build warning telling you to set fetch-depth: 0.

[sphinx.intersphinx]#

Optional

Configurations related to Intersphinx for linking to other Sphinx projects.

[sphinx.intersphinx.projects]#

Optional

A table of Sphinx projects. The labels are targets for the external role. The values are URLs to the root of Sphinx documentation projects.

[sphinx.intersphinx.projects]
sphinx = "https://www.sphinx-doc.org/en/master/"
documenteer = "https://documenteer.lsst.io"
python = "https://docs.python.org/3/"

See the Intersphinx documentation for details on linking to other Sphinx projects.

[sphinx.intersphinx.cache]#

Optional

Configurations for prefetching intersphinx inventories from the Ook inventory cache service (the documenteer.ext.intersphinxcache extension).

By default, Documenteer prefetches each intersphinx project’s object inventory (objects.inv) from the Ook inventory cache service and rewrites intersphinx_mapping to point at the locally-written files, so documentation builds no longer depend on third-party site availability. Only the inventory locations are rewritten — the target URIs are left unchanged, so resolved links still point at the real upstream sites.

Prefetching requires a bearer token for the Ook API, read from the OOK_TOKEN environment variable. When the token is unset, the extension is a complete no-op and stock Intersphinx behavior is unchanged, so builds still work for projects that haven’t configured the token (for example, fork pull requests where secrets are unavailable, or local builds). When the service fails for an individual inventory (an unauthorized or rejected token, an unreachable service, a server error, or a timeout), that mapping entry is left untouched so Intersphinx fetches the origin directly, and the build reports the fallback at the INFO log level naming the inventory. The fallback is logged at INFO rather than as a warning on purpose: Rubin documentation builds run with warnings-as-errors (-W), so reporting graceful service degradation as a warning would fail the build. An Ook outage can never make a build worse than a build without the service.

To avoid re-downloading inventories on every build, Documenteer caches each prefetched objects.inv on disk and only revalidates it with Ook after a short time-to-live (see disk_cache_ttl below). While a cached inventory is younger than the TTL, it is reused without contacting Ook at all; once the TTL has expired, Documenteer revalidates conditionally with an If-None-Match request, and a 304 Not Modified reuses the on-disk copy with no inventory body transferred.

The inventory prefetch summary#

Once the prefetch is done, Documenteer logs one summary block naming every mapping entry it considered, in [sphinx.intersphinx.projects] order — the order you see in your own configuration file:

Intersphinx inventory prefetch summary (Ook cache status):
  python    hit           fetched 2026-08-18T17:58:24Z (26 minutes ago)
  sphinx    stale         fetched 2026-08-18T15:24:30Z (3 hours ago)
  numpy     miss          fetched 2026-08-18T18:24:28Z (just now)
  pydantic  hit           fetched 2026-08-09T18:24:30Z (9 days ago)      -> moved
  astropy   served        fetch time unavailable
  safir     disk cache    (Ook was not contacted)
  requests  direct fetch  (Ook could not be reached)

The whole block is logged at INFO, so it never affects a warnings-as-errors (-W) build: none of what it reports is yours to fix. Entries Documenteer doesn’t prefetch at all — a local target URI, or an inventory location that’s already a local path — get no row.

The second column is how that inventory was obtained. Three of its values come from Ook, passed through verbatim, and describe the state of Ook’s copy:

hit

Ook served its cached copy, which was still within its own freshness lifetime.

stale

Ook served its cached copy, which is past its freshness lifetime. On its own this is a normal Ook serve, not an error — see below.

miss

Ook had no usable cached copy, so it fetched the inventory from the origin site to answer the request.

The remaining values are Documenteer’s own, and describe what the client did:

served

Ook answered but sent no cache-status header, so all that’s known is that Ook served the inventory. This is what an Ook deployment older than the cache-status header looks like.

disk cache

Documenteer’s own on-disk TTL fast path answered this entry and Ook was never contacted for it — see disk_cache_ttl.

direct fetch

The prefetch fell back to the origin: Documenteer left this mapping entry untouched, so Intersphinx fetched objects.inv from the upstream site itself, exactly as it would without the service. The reason is in parentheses on the same row, and the matching per-entry INFO line above the block carries the full error.

The third column is when Ook last confirmed that inventory with its origin site — not when the bytes it served to you were downloaded. A background refresh that the origin answered with 304 Not Modified keeps Ook’s stored bytes and still advances this time. It’s reported as the absolute UTC instant, so a row can be correlated with Ook’s own logs, followed by a humanized age for eyeballing. Rows that explain themselves in parentheses (disk cache and direct fetch) report no fetch time, because Ook was either never asked or never served the inventory; an Ook-served row for which the service sent no usable time reads fetch time unavailable rather than showing a placeholder that would read as an age.

A -> moved flag marks a row whose configured inventory URL Ook reports as permanently moved. The destination URL, and what to do about it, are in that entry’s own notice rather than in the table; see warn_on_permanent_redirect.

Important

A stale row on its own is not a problem, and there’s nothing to do about it. Ook deliberately keeps serving a copy that’s past its freshness lifetime while a background job revalidates it, so that a slow or briefly unavailable origin site can’t break your build. That availability is the entire point of the cache.

What’s worth acting on is stale paired with an old fetch time. That combination means Ook’s refreshes for that inventory have been failing for as long as the fetch time is old, so the copy you’re building against really is drifting from the origin. Report it in #square-docs-support on Slack.

use_service#

Optional

Whether to prefetch intersphinx inventories from the Ook inventory cache service. Default is true.

Set this to false as an escape hatch to disable prefetching so Intersphinx fetches every inventory directly from its origin site:

[sphinx.intersphinx.cache]
use_service = false

With use_service = false the service is never contacted, even when an OOK_TOKEN is set.

service_url#

Optional

Base URL of the Ook API that hosts the intersphinx inventory cache service. Default is https://roundtable.lsst.cloud/ook.

disk_cache_ttl#

Optional

How long, in seconds, a prefetched inventory on disk is reused before Documenteer revalidates it with the Ook service. Default is 600 (10 minutes).

While a cached objects.inv is younger than the TTL, Documenteer reuses it as-is and makes no request to Ook, so rapid successive local rebuilds skip the round-trip entirely. Once the TTL has expired, Documenteer revalidates the inventory conditionally: it sends the ETag it stored alongside the cached file as an If-None-Match header, and if Ook answers 304 Not Modified the on-disk copy is reused with no inventory body transferred and its TTL window restarts. A 200 OK response replaces the cached inventory.

Set disk_cache_ttl to 0 to disable this fast path so every build revalidates with Ook:

[sphinx.intersphinx.cache]
disk_cache_ttl = 0

The TTL governs only the client-to-Ook hop; whether Ook’s own cached copy is current relative to the origin site remains Ook’s concern.

warn_on_permanent_redirect#

Optional

Whether to report a permanently-moved intersphinx inventory URL as a Sphinx warning rather than at the INFO log level. Default is false.

When the Ook service reports that one of your configured inventory URLs now redirects permanently to a new location, Documenteer tells you so in the build log, naming the mapping key, the URL you configure, where it now lives, and the [sphinx.intersphinx.projects] entry to update. By default that notice is logged at INFO: the move originates upstream, outside your control, and Rubin documentation builds run with warnings-as-errors (-W), so warning about it would fail your builds on a third party’s schedule.

Set this to true if you would rather your build fail than carry a stale inventory URL:

[sphinx.intersphinx.cache]
warn_on_permanent_redirect = true

The setting escalates only that one notice. The inventory summary block stays at INFO either way, so opting in never turns a block of pure status reporting into a build failure, and prefetching is unaffected — the mapping entry is still rewritten to the locally cached inventory whether or not escalation is enabled.

The escalated notice carries the warning subtype documenteer.intersphinx_permanent_redirect, so you can silence a move you already know about — one you can’t act on yet, for instance — while keeping the warning for every other inventory:

# conf.py
suppress_warnings = ["documenteer.intersphinx_permanent_redirect"]

Note that Ook reports the redirect chain it observed at its last successful fetch of the inventory, not at your build time.

[sphinx.linkcheck]#

Optional

Configurations for the linkcheck builder, which checks the external links in the documentation.

By default, Documenteer replaces Sphinx’s built-in linkcheck builder with a builder backed by the Ook link-check service (the documenteer.ext.linkcheckservice extension). Instead of checking every link in-process, the builder submits the project’s external links to the service and polls for the results. The service caches results and retries failing links over time, so documentation builds no longer fail on transient third-party outages.

The service requires a bearer token for the Ook API, read from the OOK_TOKEN environment variable. If the token is missing or rejected, the builder falls back to Sphinx’s built-in in-process linkcheck builder in every mode, so link checking still runs for projects that haven’t configured the token (for example, fork pull requests where secrets are unavailable, or CI that doesn’t forward the token). The built-in check’s own result then decides the build’s exit status. If instead the service is unreachable or the polling budget is exhausted, the build falls back the same way by default: the builder reports the service problem at the INFO log level and checks the links in-process. An outage therefore costs the build time — every link is visited from the machine running the build, with none of the service’s caching or retry buffering — rather than costing it link checking, and broken links the in-process check finds fail the build as they always do. Set strict to true to fail the build on the service problem itself instead. Links the service reports as broken always fail the build, regardless of the strict setting.

ignore#

Optional

List of URL regular expressions patterns to ignore checking. These are appended to the linkcheck_ignore configuration.

Ignored URLs apply to both the service-backed builder (matching URLs are never submitted to the service) and Sphinx’s built-in linkcheck builder.

use_service#

Optional

Whether to check links with the Ook link-check service instead of Sphinx’s built-in linkcheck builder. Default is true.

Set this to false as an escape hatch to restore Sphinx’s built-in linkcheck builder, which checks each link in-process and doesn’t require an Ook API token:

[sphinx.linkcheck]
use_service = false

With use_service = false the built-in builder is selected outright and the service is never contacted, even when an OOK_TOKEN is set. This differs from the automatic token fallback under the default use_service = true, where the builder uses the service when a token works and only falls back to the built-in in-process check when the OOK_TOKEN is missing or rejected.

service_url#

Optional

Base URL of the Ook API that hosts the link-check service. Default is https://roundtable.lsst.cloud/ook.

poll_budget#

Optional

Maximum time, in seconds, to wait for link-check results from the service. Default is 300.

If the budget is exhausted before the service completes the check, the build falls back to Sphinx’s built-in in-process linkcheck builder — or fails, if strict is true.

strict#

Optional

Whether genuine link-check service problems fail the build. Default is false: when the service is unreachable or the poll_budget is exhausted, the builder reports the problem at the INFO log level and falls back to Sphinx’s built-in in-process linkcheck builder, whose own result then decides the exit status. Nothing is skipped, so an outage doesn’t silently stop checking your links; it does mean a build during one takes as long as a full in-process link check, and broken links that check finds fail the build.

Set this to true to fail the build on the service problem itself instead, with no fallback:

[sphinx.linkcheck]
strict = true

Use it when a substitute check isn’t what you want — when the point of the build is that the service was consulted, or when you’d rather see an outage immediately than pay for the in-process check.

This setting only gates genuine service availability problems. A missing or rejected OOK_TOKEN is not one of them: rather than failing, the builder falls back to Sphinx’s built-in in-process linkcheck builder in every mode (including under strict), so link checking still runs. Links the service reports as broken always fail the build, regardless of this setting.

recheck_unverified#

Optional

Whether URLs the service couldn’t verify from its own vantage point are rechecked from the build’s. Default is true.

Two of the service’s verdicts rest on evidence nobody actually obtained about the link:

Blocked URLs. Some sites sit behind a bot-protection edge (typically Cloudflare) that answers the service’s requests with a 403 no matter how ordinary the request is. The service can’t tell such a URL apart from one that’s genuinely refusing everyone, so it reports the URL as blocked: a caveat rather than a failure, never counted as broken.

URLs the service couldn’t reach at all. When a request gets no response — a TLS chain the service can’t build, a connection the far end drops, a name it can’t resolve — the service reports the URL broken with no HTTP status code. That verdict does fail the build, and it’s the one worth the most scrutiny: nothing about it is specific to the link rather than to the service’s own network.

A documentation build usually runs somewhere else entirely — a GitHub Actions runner the same site is happy to serve, with its own trust store and its own route — so the build can often settle what the service couldn’t. Documenteer rechecks exactly those URLs, and no others, from the machine running the build, sending the same request Sphinx’s built-in linkcheck builder would send. The checks are sequential with a short delay between them, so a handful of rechecks never arrives at a site as a burst.

A broken result that does carry a status code is never rechecked. That’s a definite answer from the server itself — a 404 is a 404 from every vantage point — and a second opinion has no standing to overturn it.

What the build observes is merged into that same build’s report:

  • A URL the build resolves is reported ok (or redirected, if it works only through a permanent redirect), and its bot-protection caveat, or the failure the service couldn’t reproduce, clears.

  • A URL that answers the build with a definite failure (a 404, say) is reported broken, with the build’s own evidence — which fails the build, as any broken link does.

  • A URL blocked from the build’s vantage point too keeps its blocked status, its caveat, and the service’s own evidence: the recheck settled nothing, so nothing is rewritten.

  • So does a URL that answers the build with nothing at all — a timeout, a connection reset, a DNS failure. Bot protection doesn’t always answer with a status code, and a runner’s network blip is not evidence about a link, so only a failure the server itself answered with is allowed to turn the service’s caveat into a build failure.

  • A URL the service couldn’t reach and the build can’t reach either stays broken and still fails the build. Two vantage points coming back empty-handed isn’t proof the link works; its detail line says both looked, so you can tell it apart from one nobody checked twice.

The linkcheck.json artifact reflects the merged view, and flags each result the build rechecked for itself with locally_rechecked.

The observations the build actually obtained are also contributed back to the service, so the next project to reference the URL benefits from them — see Contributing rechecked results back to the service, below.

Set this to false to skip the recheck, and the contribution along with it, and report the service’s verdict as-is:

[sphinx.linkcheck]
recheck_unverified = false

Contributing rechecked results back to the service#

A build that settles a URL the service could only report as blocked knows something the service can’t learn from its own vantage point. Documenteer hands that knowledge back: whenever the recheck finds blocked URLs, the builder posts what it observed — successes and failures alike, since a URL that’s blocked from the runner too is evidence as well — to the check’s contributions endpoint on the Ook API. Each contributed result carries the same evidence the recheck merged into this build’s report: the final status code, any redirect that was followed, and the error text when the request failed outright. A URL that answered the build with nothing at all is one exception: a contribution is applied to state every other project’s build reads, so an observation the build wouldn’t apply to its own report — a timeout or a dropped connection settles nothing about a link — isn’t handed on as shared evidence either. The other is a URL the service reported broken: the service only applies a contributed result to a URL its own stored state has as blocked, so an observation for one it reported broken would come back rejected, and Documenteer withholds it rather than sending it to be refused. Those URLs are still rechecked, and what the build observes still informs this build’s own report. A build whose links the service settled on its own has nothing to contribute, and doesn’t so much as mint a token — which is the overwhelmingly common case.

Contributions are attested with a GitHub Actions OIDC id token rather than a shared secret, so the service records the verified claims of the workflow run — the repository it ran in — as the provenance of every result it applies. Documenteer mints that token with the configured service_url as its audience, which scopes it to one deployment: a token minted for a development Ook can’t be replayed against production, and there’s no separate audience setting to keep in sync. The request also carries the same OOK_TOKEN bearer the rest of the link check uses; both are required. Alongside the results it describes the run — the repository and run URL from the Actions environment, and the Documenteer version that made the observations — but those fields are advisory only, and the service takes the provenance it records from the token’s claims instead.

Contributing needs the id-token: write permission, because that’s what makes GitHub expose the OIDC token endpoint to the job:

.github/workflows/ci.yaml#
jobs:
  docs:
    runs-on: ubuntu-latest
    permissions:
      contents: read
      id-token: write  # contribute link-check results to Ook
    steps:
      # ...

Important

A reusable workflow can’t ask for a permission of its own: permissions come from the calling job, and a called workflow can only narrow them. If your documentation build runs through a shared workflow, add permissions: id-token: write to the job in your own repository that calls it, and confirm with that workflow’s maintainers that its build job passes the permission through rather than narrowing it away. Both sides have to be in place before a contribution can be attested.

A run that contributes says so in its build log, first from the recheck and then from the contribution:

Local recheck: 3 verified, 1 still blocked, 0 failing
Contributed 4 link-check results to lsst-sqre/documenteer (4 accepted, 0 rejected)

Nothing about a contribution can fail the build. It improves somebody else’s future build, so it’s never allowed to cost this one — not even under strict, which gates service availability problems only. Every way it can go wrong is reported at the INFO log level rather than as a warning, which is what keeps that promise for a build run with -W (warnings as errors), where a warning is a failure:

  • Where no id token can be minted, the local recheck still runs and still informs this build’s report, and only the contribution is skipped, with a note naming the id-token: write permission — because the absence looks identical whether the build is on a laptop, where there’s nothing to fix, or in a workflow that never asked for the permission, where there’s one line to add.

  • The service applies a batch entry by entry, so an entry it declines (a URL that isn’t one of the check’s members, say, or one that isn’t blocked because its own vantage point already settled it) is reported per URL with the service’s reason, and the rest of the batch still applies.

  • A batch that can’t be delivered at all is retried for the failures the service documents as retryable — a 502 while it can’t reach GitHub’s signing keys, and connection failures — up to three times after the first attempt, on a backoff that starts at half a second and doubles. If those attempts are exhausted, the builder reports it and moves on; the build’s exit status is unchanged. A response that would fail identically however often it’s sent, such as a 422 for a batch the service won’t accept, is reported the same way on its first response instead of being retried.

origin_base_url#

Optional

The origin base URL the links are submitted for: the full base URL of the published website (for example, https://documenteer.lsst.io). The link-check service uses the origin to associate the submitted URLs with the website. By default the origin is the project.base_url setting, so most guides don’t need to set this override. The URL is normalized the way the service normalizes origins: the host is lowercased and any trailing slash is stripped.

[sphinx.linkcheck]
origin_base_url = "https://documenteer.lsst.io"