docs: ship the openarmature docs site (Phase A)#32
Merged
Conversation
Implements PR-A of the docs-mkdocs-launch coord thread: a buildable MkDocs Material site at docs/, a docs CI workflow deploying to Cloudflare Pages on push-to-main, and AGENTS.md as the canonical agent-discovery file (CLAUDE.md becomes a literal pointer). The site itself is placeholder content — index.md plus four section index pages (Getting Started, Concepts, Reference, Contributing) for PR-C and PR-D to fill. mkdocs.yml is forked from pydantic-ai's, stripped to our shape, with site_url set to https://docs.openarmature.ai/ so social cards and SEO are correct day one. Custom dark + light theme styling lives in docs/stylesheets/extra.css: unified surface color per theme (footer-bg in dark; #fbfefb in light), 1px gray section dividers, #9d4edd accent for links and active nav, slightly-rounded gray-outlined search, minimalist weather-sunny / weather-night theme toggle icons, no drop shadow under the top nav. Default Material book-icon logo and auto-generated site-name header in the sidebar are suppressed since we have an explicit OpenArmature nav entry that links home. The deploy step in docs.yml needs CF_API_TOKEN + CF_ACCOUNT_ID repo secrets to actually deploy; the build step works regardless. PR checks build with --strict; deploy fires only on push to main. Tests: 401 passed, 2 skipped (existing). ruff + pyright clean. mkdocs build --strict in 0.4s with zero warnings.
Plain-copy the 5 demo projects from the sibling openarmature-examples repo into examples/. Drops per-demo pyproject.toml + uv.lock + IDE metadata; the demos now live alongside the source and depend on openarmature directly rather than via path source. Adds an ``examples`` dependency group with ``openai`` (the only extra dep the demos use). Wheel already excludes examples/ by virtue of ``packages = ["src/openarmature"]``; verified by inspecting a fresh build. Adds tests/test_examples_smoke.py: each demo's main.py is loaded via runpy with a sentinel run_name so module-level imports execute but the ``if __name__ == "__main__":`` block doesn't. Catches syntax / import / public-API breakage without needing a live LLM endpoint. Adds pytest-examples to dev deps for the upcoming docs-page code blocks (configured in a later commit). Tests: 406 passed, 2 skipped. ruff + pyright clean.
Convert two OpenAI-shape error-handling helpers from package-private to public so third-party Provider implementations targeting any OpenAI-compatible endpoint (vLLM, LM Studio, llama.cpp server, Anthropic gateway shims, etc.) can reuse the spec §7 wire-mapping without reimplementing it. - ``_classify_http_error``: converted from OpenAIProvider method to free function (body never referenced ``self``). Renamed to ``classify_http_error``. Reused by the Provider's own _do_complete path. - ``_parse_retry_after``: renamed to ``parse_retry_after``. Same body. Both are re-exported from ``openarmature.llm`` so consumers don't need to reach into ``openarmature.llm.providers.openai``. Tests in tests/unit/test_llm_provider.py updated to call the free functions directly; the no-longer-needed ``_make_provider`` helper was removed. Tests: 406 passed, 2 skipped. ruff + pyright clean.
Replace the docs/getting-started/index.md placeholder with a real Quickstart: install, define a two-node graph with the append reducer, run it, see the result. No LLM required — the smallest possible openarmature program so the whole shape fits on one screen. Adds tests/test_docs_examples.py: every Python code block in docs/ is run as a test via pytest-examples. Catches docs drift — a refactor that breaks a snippet's imports or API now fails CI before the docs site can mislead a reader. Non-Python blocks (bash, toml) are filtered out at parametrize time. The Quickstart code block ends with an ``assert`` rather than a ``print`` so pytest-examples can run it cleanly without expected- output bookkeeping. Reader still sees the value via the assert. Tests: 407 passed, 2 skipped. mkdocs build clean.
Walks through implementing the Provider Protocol for a non-default wire format (Anthropic Messages, Bedrock, an internal gateway, etc.). The shipped OpenAIProvider is comprehensive at ~465 lines; this guide shows the minimum (~60 lines) plus a contract checklist covering statelessness, non-mutation, boundary validation via validate_message_list / validate_tools, and the spec §7 error-mapping table. The skeleton uses the newly-public classify_http_error so OpenAI- compatible-but-not-OpenAI Provider authors don't reimplement the non-200 mapping table — the largest single chunk OpenAIProvider spends source lines on. Nav updates ``Getting Started`` into a section with Quickstart + Authoring a Provider as siblings. Code block runs cleanly under pytest-examples (class + helper definitions only; no module-level network calls).
Per-subpackage autodoc pages backed by each module's existing __all__ declaration: openarmature.graph, openarmature.llm, openarmature.checkpoint, openarmature.observability. mkdocstrings walks each subpackage's public surface and renders class/function docs from the (already extensive) docstrings — zero manual writing needed for the reference layer. The graph subpackage's __all__ is the broadest (state, builder, edges, nodes, projections, fan-out, middleware, observer, reducers, errors); the others are smaller and focused. The reference index links out to each. Nav: Reference section now expandable, with the index + four subpackage pages as siblings. mkdocs build --strict passes — every public symbol has a docstring mkdocstrings can render without warnings.
Adds the mkdocs-llmstxt plugin so every build produces: - ``/llms.txt`` — short table-of-contents-style summary with links to each docs page (~20 lines). - ``/llms-full.txt`` — every docs page concatenated into one plain-text file (~1500 lines on current content) for AI coding assistants that prefer one-shot ingestion. Pages are grouped under Getting Started / Concepts / Reference per the site's nav structure. Configures the Material theme's version dropdown to use ``mike`` as its provider. The dropdown stays hidden until at least one version is published (``mike deploy <version>``); pre-1.0 it's effectively no-op so the site reads as single-version. First mike deploy happens at v1.0 launch.
Replace the placeholder docs/index.md with a real landing: project tagline, primary CTAs (Get started / GitHub), and a six-card feature grid covering the load-bearing differentiators — typed/frozen state, compile-time checks, observability without buy-in, checkpointing, fan-out, async-first + LLM-agnostic shape. No code block on the landing intentionally — Quickstart owns that. The landing's job is the 5-second "should I care?" read. Adds pymdownx.emoji + Material's emoji extension so the ``:material-X:`` icon shorthand renders. Front-matter hides nav + toc for a cleaner full-width landing layout (Material convention). Pre-commit's check-yaml hook gets ``--unsafe`` so it can parse the ``!!python/name:`` tags Material requires for its emoji extension. ``--unsafe`` skips constructor validation but still catches malformed YAML, which is the bug class the hook is actually for.
Replace the docs/concepts/ placeholder with six focused pages
covering the framework's conceptual surface, restructured around
first-touch comprehension rather than the spec-vocabulary
walkthrough in coord/docs/concepts.md:
- index.md — overview + reading order
- state-and-reducers.md — state, reducers, partial updates, why
history is opt-in
- graphs.md — nodes, edges, GraphBuilder, compile, invoke
- composition.md — conditional edges, subgraphs, projection
(FieldNameMatching / ExplicitMapping / custom)
- fan-out.md — N parallel subgraph instances, concurrency
bound, error policy, per-instance observability
- observability.md — node-boundary hooks, NodeEvent shape, serial
delivery, drain(), OTel mapping
- checkpointing.md — when, why, two built-in backends, what it isn't
Lead with why before how. Trim spec-section references at the
expense of less back-pointer density. Keep code snippets short and
focused; full programs live in Quickstart + examples/.
pytest-examples is reconfigured to skip illustrative snippets in
concept pages (they reference names by design) and only run full
programs under getting-started/. Drift detection stays via
Quickstart + Provider skeleton + auto-generated reference.
Nav: Concepts section expands into seven entries.
Tests: 408 passed, 28 skipped. mkdocs build clean.
There was a problem hiding this comment.
Pull request overview
Phase A rollout of a MkDocs Material documentation site for OpenArmature (with CI build + Cloudflare Pages deploy), plus in-repo runnable examples and doc-driven drift detection. It also promotes the OpenAI provider’s HTTP error classification helpers to a public, reusable API surface.
Changes:
- Add
docs/MkDocs site (theme styling, concepts/getting-started/reference pages, mkdocstrings config) and a Cloudflare Pages deployment workflow. - Vendor runnable demos under
examples/and add smoke tests + pytest-examples execution for docs snippets. - Make OpenAI wire error helpers public (
classify_http_error,parse_retry_after) and re-export them fromopenarmature.llm.
Reviewed changes
Copilot reviewed 35 out of 37 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| tests/unit/test_llm_provider.py | Update unit tests to call public helper |
| tests/test_examples_smoke.py | Add smoke test loading example main.pys |
| tests/test_docs_examples.py | Execute selected docs Python blocks in CI |
| src/openarmature/llm/providers/openai.py | Promote error helpers to public functions |
| src/openarmature/llm/providers/init.py | Re-export new provider helpers |
| src/openarmature/llm/init.py | Re-export new provider helpers at package root |
| pyproject.toml | Add docs/examples dependency groups + pytest-examples |
| mkdocs.yml | Configure MkDocs Material site + plugins/nav |
| examples/README.md | Document available demos + how to run |
| examples/01-linear-pipeline/main.py | Add demo: minimal linear pipeline |
| examples/02-routing-and-subgraphs/main.py | Add demo: conditional routing + subgraphs |
| examples/03-explicit-subgraph-mapping/main.py | Add demo: reuse subgraph with ExplicitMapping |
| examples/04-observer-hooks/main.py | Add demo: observer hooks + metrics |
| examples/05-nested-subgraphs/main.py | Add demo: deep subgraph nesting invariants |
| docs/stylesheets/extra.css | Add custom light/dark theme overrides |
| docs/reference/index.md | Add API reference landing page |
| docs/reference/graph.md | Add mkdocstrings page for openarmature.graph |
| docs/reference/llm.md | Add mkdocstrings page for openarmature.llm |
| docs/reference/checkpoint.md | Add mkdocstrings page for openarmature.checkpoint |
| docs/reference/observability.md | Add mkdocstrings page for openarmature.observability |
| docs/index.md | Add landing/marketing home page |
| docs/getting-started/index.md | Add Quickstart runnable snippet |
| docs/getting-started/provider-authoring.md | Add Provider authoring guide + skeleton |
| docs/contributing/index.md | Add contributing section stub |
| docs/concepts/index.md | Add concepts section index |
| docs/concepts/state-and-reducers.md | Add state/reducer conceptual docs |
| docs/concepts/graphs.md | Add graph builder/compile/invoke conceptual docs |
| docs/concepts/composition.md | Add conditional/subgraph/projection conceptual docs |
| docs/concepts/fan-out.md | Add fan-out conceptual docs |
| docs/concepts/observability.md | Add observer hooks conceptual docs |
| docs/concepts/checkpointing.md | Add checkpointing conceptual docs |
| CLAUDE.md | Redirect to AGENTS.md |
| AGENTS.md | Add canonical agent-oriented repo guidance |
| .pre-commit-config.yaml | Allow unsafe YAML tags for mkdocs.yml |
| .gitignore | Ignore MkDocs build output and cache |
| .github/workflows/docs.yml | Add docs build + CF Pages deploy workflow |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
uv sync --all-extras installs PEP 621 optional-dependencies but not PEP 735 dependency-groups, so the new examples group (which carries openai) wasn't installed in CI. test_examples_smoke loads each demo's main.py via runpy; module-level ``from openai import AsyncOpenAI`` fired ModuleNotFoundError at collection time. Surfaced by CoPilot reviewer on PR #32.
Address spec-side review on coord thread docs-mkdocs-launch (file
04-spec-pr-feedback.md). Independently verified every cited finding
against the actual source on this branch before editing:
- ``concepts/fan-out.md`` — every config field name was wrong. Rewrite
against actual FanOutConfig (items_field / item_field / collect_field
/ target_field / count / concurrency / error_policy "fail_fast"|
"collect" / on_empty "raise"|"noop" / count_field / inputs /
extra_outputs / instance_middleware / errors_field). Document both
modes (items_field vs count, including callable count). Correct
namespace claim — instances share the fan-out node's namespace and
are disambiguated by fan_out_index, not a synthetic
"fan_out_instance_N" element. Link to spec proposal 0009 for the
v2 per-instance fan-out resume story rather than speculatively
describing v2 behavior.
- ``concepts/checkpointing.md`` — four substantive errors:
- Saves are synchronous-by-contract, not async — crash-safety
depends on it (spec §10.3).
- Resume on missing record raises CheckpointNotFound, not "starts
fresh" (spec §10.4 step 1, code at compiled.py:434).
- Checkpointer Protocol has four methods (save/load/list/delete)
with the right signatures, not three with the wrong signatures.
- CheckpointRecord carries completed_positions (history) not "next
node to run"; plus correlation_id, parent_states, last_saved_at,
fan_out_progress.
- ``concepts/observability.md`` — NodeEvent shape was the pre-v0.6.0
version. Add phase / attempt_index / fan_out_index /
fan_out_config. Document the started/completed pair model and the
checkpoint_saved opt-in phase. Routing-error story is reversed: edge
errors land on the preceding node's completed event (spec proposal
0012 / v0.9.0, code at compiled.py:624-634). Add the missing
TracerProvider isolation section (spec §6 Langfuse-double-export
rationale), detached trace mode (detached_subgraphs /
detached_fan_outs), and correlation_id introduction (separate join
key from invocation_id).
- ``concepts/graphs.md`` — invoke() loop adds the event-dispatch step
(per spec graph-engine §3 step 3) and flags that edge / routing
errors attach to the preceding completed event rather than producing
a new one.
Spec review correctly identified all of these against v0.10.0 spec.
The structural / theming work and Quickstart were unaffected.
The Provider authoring skeleton constructed Usage with the wrong field names (input_tokens / output_tokens — they don't exist; real fields are prompt_tokens / completion_tokens / total_tokens), missed the required total_tokens entirely, and used 0 sentinels when spec §6 mandates None for unreported usage. With Usage's extra="forbid", a new Provider author copy-pasting the skeleton would get a ValidationError on first call. Rewrite the Usage construction to match the actual Pydantic model and pass through None when the wire response omits the field. Also soften the contract checklist's list-validation bullet: "system-first-only" reads as "system is required first" — spec is that system is optional but, when present, must be the first message. Reword for accuracy. Surfaced as C8 in spec-side review (coord thread docs-mkdocs-launch/04). Verified against src/openarmature/llm/response.py:32-43 before editing.
mkdocs.yml has ``exclude_docs: RELEASING.md`` so the file isn't rendered as a site page; the contributing-page link pointing at it dead-ends. Replace with an external link to the file on GitHub and note that it's contributor-internal. Surfaced as m1 in spec-side review.
The observability page's ``checkpoint_saved`` paragraph claimed a
``phases="all"`` shortcut that doesn't exist in the API. The actual
behavior: ``_coerce_subscribed`` calls ``frozenset(phases)`` on
whatever's passed, so ``phases="all"`` would iterate the string into
``frozenset({"a", "l"})`` — caught by ``SubscribedObserver``'s
post-init validator as ``unknown phase(s)``, but a wrong-then-rejected
affordance is still worse than no affordance.
Replace with a pointer to the actual ``KNOWN_PHASES`` constant
(exported from ``openarmature.graph``) for the "subscribe to every
phase" use case. Note that the existing ``ALL_PHASES`` constant is
NOT this — it's the default subscription excluding
``checkpoint_saved`` for back-compat — so referring readers to it
would mislead.
Surfaced in spec-side second-pass review (coord thread
docs-mkdocs-launch/06).
README and Quickstart now show ``uv add openarmature`` first, with ``pip install openarmature`` as the alternative line. Matches the project's "uv for everything" convention (per AGENTS.md) while keeping the pip path visible for readers who haven't moved to uv yet. README still keeps the ``uv add --editable /path/...`` pattern as the standalone "for editable local development" example.
The release process is a maintainer-internal recipe — there's no external audience for the publish-RC-then-publish-real flow, the TestPyPI/PyPI configuration, or the workflow gating table. Moving the file out of the public repo prevents an external reader from mistaking it for guidance they should follow. Changes: - ``docs/RELEASING.md`` removed from this repo. The full content is now in the private ``openarmature-coord`` repo under ``docs/openarmature-python-RELEASING.md``. - ``mkdocs.yml`` ``exclude_docs: RELEASING.md`` removed — the file no longer needs an exclusion since it no longer exists here. - ``docs/contributing/index.md`` no longer links to RELEASING.md; the page becomes a stub. Past CHANGELOG entries reference ``docs/RELEASING.md`` (e.g., the 0.5.0 entry). Those are snapshot history and intentionally not edited — the references describe what was true at that release.
Two layers of cleanup: 1. **User-facing docs** (``docs/``): index landing closing paragraph, concept pages (state-and-reducers, checkpointing, fan-out, observability, graphs), Provider authoring page, top-bar buttons styling, no-link feature cards on the landing. Spec / §X / proposal NNNN / charter references removed from the rendered Markdown. 2. **Source docstrings** (``src/``): module-level docstrings + public class and method docstrings across ``graph``, ``llm``, ``checkpoint``, ``observability`` packages. Spec citations move from inside ``"""..."""`` (which mkdocstrings auto-renders into the API reference pages) to ``#`` comments outside the docstring. Maintainers reading source still see the spec breadcrumbs; the rendered API reference no longer references the spec at all. Verified: ``grep`` of ``site/reference/*/index.html`` for ``per spec`` / ``spec §`` / ``proposal`` / ``charter §`` / ``§[0-9]`` patterns returns zero hits. Tests: 408 passed, 32 skipped. ruff + pyright clean. mkdocs build --strict clean.
Restructures Provider docs and irons out remaining theme inconsistencies after the spec-review pass. **Nav restructure.** ``Authoring a Provider`` no longer lives as a standalone page under Getting Started. New top-level section ``Model Providers`` between Concepts and Reference, with two pages: - ``model-providers/index.md`` — overview: what a Provider is, what ships (OpenAIProvider + OpenAI-compatible servers), the two-method Protocol surface, behavioural guarantees, seven error categories, a minimal direct-usage example, pointers onward. - ``model-providers/authoring.md`` — moved from ``getting-started/provider-authoring.md``; opens by pointing back to the overview rather than re-introducing concepts. ``tests/test_docs_examples.py`` now runs Python code blocks under both ``getting-started/`` AND ``model-providers/`` (the Protocol + skeleton snippets are full programs and worth drift-checking). **Dark-theme polish.** - Inline code (``--md-code-fg-color``) ``#e4c1f9`` (light lavender) to pair with the ``#9d4edd`` brand accent. - Code-inside-link ``#cd8bf4`` (mid lavender) — applies to the ``openarmature.X`` links on the API Reference index plus any other linked-code patterns. Hover left to Material's cascade. - Code-block name/identifier tokens re-scoped inside ``pre`` to ``rgba(226, 228, 233, 0.82)`` (slate body-text tone) so the inline-code lavender doesn't leak into code blocks for unclassified tokens. - Per-token highlight colours (keywords/strings/numbers etc.) reverted to Material defaults after iteration found the brand-shifted and minimalist palettes both too purple-heavy. **Light-theme polish.** - Page surface ``#f5f5f5``. - Code background ``#e9e9e9`` (subtle contrast with the page surface, no border needed). - Code-inside-link colour matches dark-theme ``#cd8bf4``. **Landing tweak.** ``View on GitHub`` button gets ``target="_blank" rel="noopener"`` so the repo opens in a new tab rather than navigating away from the docs.
Apply the breadcrumb fixes spec flagged in coord file 08: - llm/messages.py: swap §3/§4 framing — §3 is Message+ToolCall+ validation timing, §4 is Tool definition (was reversed). - graph/events.py: reframe NodeEvent's `checkpoint_saved` phase as the Python shape for §10.8 save events (§10.8 SHOULDs an event emit but leaves the shape implementation-defined). - graph/errors.py: clarify fan-out-specific error categories cover both compile- and runtime-time, not just compile. - checkpoint/__init__.py + protocol.py: add fan-out nodes to §10.3 save sources (the three sources are outermost-graph + subgraph-internal + fan-out, not two). - observability/otel/observer.py: reframe §5.1 cite (the keying is impl choice; §5.1 governs the attribute) and §4.5 cite (§4.5 is span names only; hierarchy/timing live in §4.1/§4.3). Source-comment-only — no behavior change, no public API change.
Address two CoPilot review threads on PR #32: - tests/test_examples_smoke.py: smoke test was import-only via runpy and never called build_graph(). Tightened to invoke the factory after the module load so the convention the demo docstrings describe is actually exercised — graph-compile failures now surface in CI, not just import errors. - llm/providers/openai.py: tighten classify_http_error's return annotation from Exception to LlmProviderError. Every branch already returns an LlmProviderError subclass; Exception was historical from when the helper was private. Helps typed raise callers and improves the rendered API reference.
7 tasks
chris-colinsky
added a commit
that referenced
this pull request
May 13, 2026
Tag refs are mutable; SHA pins are not. CodeQL flagged "unpinned 3rd-party action" findings 21 + 22 against the docs.yml workflow on PR #32; the same warning applied to every workflow but hadn't been triaged. Pin all sixteen action references across the four workflows to commit SHAs with the resolved version recorded as an inline comment. Action versions captured: - actions/checkout → v6.0.2 - astral-sh/setup-uv → v8.1.0 - cloudflare/wrangler-action → v4.0.0 (bumped from v3) - github/codeql-action → v3.35.4 - actions/upload-artifact → v7.0.1 - actions/download-artifact → v8.0.1 - pypa/gh-action-pypi-publish → release/v1 branch tip - softprops/action-gh-release → v2.6.2 The wrangler-action bump from v3 to v4 is the deliberate move: v4 uses node24, resolving the Node.js 20 deprecation warning that's been firing on every Docs workflow run. v4's only major change is bumping the bundled Wrangler CLI default from v3 to v4, which is transparent to our `pages deploy` invocation. The maintenance pair is .github/dependabot.yml — Dependabot watches the github-actions ecosystem and surfaces version bumps as PRs each month, so SHA-pinning's "no auto-updates" downside gets handled automatically. Monthly cadence keeps PR volume bounded; action releases cluster around new runner features and platform updates, so a month is long enough for batching without missing real security advisories. After merge, the open CodeQL findings 21 + 22 on PR #32 should be auto-dismissed once the next CodeQL scan re-runs against the pinned workflows.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Phase A of the docs site initiative (coord thread
docs-mkdocs-launch).A buildable MkDocs Material site at
docs/, deployed to Cloudflare Pageson push-to-main, with first-touch docs, API reference, and pytest-examples
wiring for drift detection.
What's in this PR
Nine commits, each a separable concern:
mkdocs.yml, plugin pins,GH Actions docs workflow, AGENTS.md as canonical agent-discovery
(CLAUDE.md → pointer), per-theme styling (dark with unified surface +
#9d4eddaccent; light with#fbfefbsurface).smoke test runs each
main.pyviarunpyto catch API drift withoutneeding a live LLM endpoint. (Archive of the sibling repo is a manual
step post-merge.)
were package-private helpers on
OpenAIProvider; now public, reusableby third-party Providers. Tests updated.
a minute to a running graph). pytest-examples runs the full code block
as a test.
checklist for authoring a Provider against a non-default wire format.
reference (graph / llm / checkpoint / observability) from existing
docstrings.
/llms.txt+/llms-full.txtfor AI coding assistants;mikeversioning configuredbut no published versions yet.
docs/index.mddoubles asthe marketing landing (per the docs-site-plan); 6-card feature grid,
primary/secondary CTAs, hidden nav + toc for full-width layout.
pages under
docs/concepts/: state-and-reducers, graphs, composition,fan-out, observability, checkpointing.
Cloudflare setup (manual, before deploy works)
The
Deploy to Cloudflare Pagesstep in.github/workflows/docs.ymlneeds two repo secrets to succeed:
CF_API_TOKEN— scoped to theopenarmature-docsPages projectCF_ACCOUNT_ID— the LunarCommand account IDPR builds only run the build job (deploy is gated on push-to-main).
After merge, the deploy step needs the secrets to actually push to CF
Pages; until then it will fail (harmless — the rest of CI is unaffected).
Domain decisions (from the coord thread)
openarmature.ai;.com/.org301-redirect to it.docs.openarmature.ai.openarmature.ai/docs/(pydantic-style) with a separatemarketing app at apex. Its own thread, post-Phase A.
Test plan
uv run mkdocs serveand walk through Quickstart, Providerauthoring, each Concepts page, the four reference pages, and toggle
light/dark.
uv run pytest -q— 408 passed, 28 skipped.uv run pyright src/ tests/— 0 errors.uv build && unzip -l dist/openarmature-0.5.0-py3-none-any.whl | grep -E "(examples|docs)"returns nothing.docs.openarmature.ai(or the temporary*.pages.devURL untilthe custom domain is wired).
openarmature-exampleson GitHub with a redirect note inits README.