Skip to content

docs: publish documentation as a GitHub Pages site and run a full quality pass#146

Merged
sourcehawk merged 37 commits into
mainfrom
worktree-docs-github-pages
Jun 2, 2026
Merged

docs: publish documentation as a GitHub Pages site and run a full quality pass#146
sourcehawk merged 37 commits into
mainfrom
worktree-docs-github-pages

Conversation

@sourcehawk
Copy link
Copy Markdown
Owner

@sourcehawk sourcehawk commented Jun 2, 2026

Description

Publishes the project documentation as a Material for MkDocs site on GitHub Pages, and runs a comprehensive quality pass over the entire documentation set. Every page is rewritten to a consistent standard with API references verified against source, a hands-on getting-started tutorial is added, and the README is trimmed to a minimal entry point that links to the site.

Changes

  • Docs site: mkdocs.yml (Material theme: instant search, dark mode, code copy, content tabs, Mermaid), a pinned requirements-docs.txt, and .github/workflows/docs.yml that builds the site in --strict mode on pull requests and publishes to GitHub Pages when a release is published (so the live site tracks the latest released version), with a manual workflow_dispatch for ad-hoc publishing. Adds make docs-serve and make docs-build for local preview.
  • Full content pass: every page (Component, Primitives Overview and the 22 primitive reference pages, Custom Resources, Guidelines, Testing, Compatibility) rewritten to one standard, with references checked against source and Mermaid diagrams where they clarify (reconciliation lifecycle, status model, primitive-category decision, plan-and-apply). The primitive pages are standardized on one template and link shared concepts to the overview instead of repeating them.
  • New: a curated landing page and a step-by-step Getting Started tutorial grounded in a runnable example.
  • Restructured: the Testing guide around three layers (mutation, resource, component) with goldengen coverage and AssertComplete; the Guidelines into a practical set grounded in real production usage.
  • Adopts the feature.NewBooleanGate and component.OrphanWhen conveniences across the docs and examples.
  • README trimmed from ~430 to ~116 lines, pointing at the published site.

Challenges

Several example fixtures were genericized so the public docs and examples carry no consumer-specific naming, and the mutations-and-gating example was reworked to demonstrate all three testing layers (including goldengen.Resource/Component coverage). Prettier and Mermaid have a couple of sharp edges that are now handled: grid-card lists need 4-space indentation protected from the formatter, and a semicolon in Mermaid note text silently breaks the whole diagram.

Testing

mkdocs build --strict is clean (zero broken links or anchors), and the same strict build runs on every pull request via the new workflow. make all passes: formatting, lint, the full unit and envtest suite, example tests, and example builds, including the version-matrix and the reworked mutations-and-gating example.

Manual step required

In repository Settings → Pages, set Source = GitHub Actions so the deploy job can publish. With that set, the site publishes when you publish a release (or via the manual workflow_dispatch run); the sourcehawk.github.io links in the README resolve once it is live. Merging this PR alone does not publish.

sourcehawk and others added 30 commits June 2, 2026 04:53
…ks for strict build

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- Fix grid card rendering: restore 4-space body indentation required by
  Python-Markdown and protect it from prettier with a prettier-ignore marker,
  so card descriptions render inside the card box.
- Persistent left navigation on every page: drop navigation.tabs (and
  navigation.sections) so the home page and all pages show the full nav tree.
- Remove hand-written Table of Contents sections from component, primitives,
  custom-resource, and guidelines pages; Material renders the page TOC in the
  right sidebar, so the in-body TOC was redundant.
- Fix a stale in-page anchor link in component.md.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rewrite Primitives Overview as the canonical hub for cross-cutting concepts
(mutation system, boolean/version gating, editors, container selectors,
server-side apply, workload-kind-agnostic mutations, lifecycle interface to
status-value mapping), with category decision-tree and plan-and-apply Mermaid
diagrams.

Rewrite Component: rebuild the condition-priority table from source (all reasons
including the failing reasons and FeatureGateError), correct the Auxiliary()
guidance and reconciliation phase count, add reconciliation-lifecycle and
status-model diagrams, document Previewable and MutationInspector, and move
generic best practices to the Guidelines page.

Rewrite Custom Resources: fix the example resource to implement Preview()
(concepts.Previewable) and delegate MutationInspector, correct operational
status string values, document the Static builder WithGuard option and the
identity format contract, add an Integration builder example, and add a step
index. Lean pages link shared concepts to the hub.

Add Go API external link to the nav.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Landing page: add a value proposition, key-features summary, and a minimal code
taste, with the card grid as secondary navigation and a suggested reading path.

Getting Started: a hands-on first-component tutorial grounded in a real example,
covering the owner CRD contract, building ConfigMap and Deployment primitives, a
boolean-gated mutation, composing the component, wiring a thin reconciler (with
the Kubebuilder fetch-and-delegate entry point and FlushStatus status-write
semantics), and a golden test.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Standardize all 22 primitive pages on one template (capabilities, building,
mutations, internal ordering, editors, kind-specific sections, lifecycle
sections, full example, guidance). Shared cross-cutting concepts now live once
in the Primitives Overview and each page links to them rather than repeating.

Notable fixes verified against source:
- Use runtime string status values consistently (e.g. OperationPending), fixing
  service, pv, pvc, hpa, pdb which previously used wrong or Go-identifier forms.
- Add workload-kind-agnostic mutation pointers only where LiftMutation exists
  (deployment, statefulset, daemonset).
- Demonstrate WithDataExtractor on static primitives that claimed the capability
  but never showed it.
- Add the garbage-collection ownership warning and a full example to
  clusterrolebinding; remove the duplicated server-side apply section from
  cronjob; expand the previously thin pod and replicaset pages.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Guidelines: restructure into a practical guideline set grounded in real
production usage patterns (desired-state baselines, pure mutations, the
defaults/compat/overrides layering, fail-loud version floors, user-override
escape hatch, named mutations, continue-on-error across components), with
neutral examples.

Testing: lead with golden.WithScheme (effectively mandatory for typed objects),
add a which-tool-when guide, document the Previewer/ComponentPreviewer
contracts, and show the explicit go test ./path -update form.

Compatibility: add the Go minimum, clarify what Tested status means for
production, add a deprecation note and a workflow status badge.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the domain-flavored version-gating scenario (8.x versions, ClusterEnv
Pre89/Unified89 with gossip/raft discovery) with a neutral one: versions
1.0.0/1.5.0/2.0.0 and PeerDiscovery/PreV2 and PeerDiscovery/V2 mutations gated
at the 2.0.0 boundary. Regenerate the goldens and manifest, and update the
testing guide to match.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace em dashes with colons, parentheses, or sentence breaks as the context
requires, per the project writing style.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lead with the navigation (Start here) above the prose, and rewrite the value
proposition to frame the framework's full purpose (composing operators from
reusable, testable layers) rather than a single status-handling pain point.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Use the new NewBooleanGate(enabled) constructor in the Primitives Overview
boolean-gating section, the getting-started tutorial, and the mutations-and-gating
example (tracing, debug-logging, and metrics-config mutations) in place of the
verbose NewVersionGate("", nil).When(enabled) form. Drop the now-unused version
parameter from MetricsConfigMutation. Version-gated examples are unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The boolean-gating note pointed at version gating but showed no example in
context. Add a version-gated gate snippet, note that the VersionConstraint is
consumer-supplied, link the backward-compat mutation in the mutations-and-gating
example, and target the Version-Gated Mutations section directly.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Rework the example test suite to model the mutation/resource/component layers:

- Mutation level: factor minimal baselines into a shared helpers_test.go; the
  per-mutation tests keep their explicit field assertions.
- Resource level: drive the real NewDeploymentResource/NewConfigMapResource
  factory from the owner spec (instead of re-spelling the build inline), assert
  exactly which mutations fire via concepts.MutationInspector.FiringSet, and
  golden the rendered YAML.
- Component level: extract BuildComponent (shared by the controller and the
  test) and golden the whole component with AssertComponentYAML.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…spection

Build the resource through NewDeploymentResource (as the reconciler does) instead
of re-spelling the build inline, assert which mutations fire via
concepts.MutationInspector.FiringSet, then golden the output. Point to the Testing
page for the full mutation/resource/component strategy.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…s on goldengen

Replace the manual MutationInspector.FiringSet introspection in the resource
tests with goldengen.Resource: declarative fixtures across versions assert which
mutations fire (Requires/Forbids) and AssertComplete proves every registered
mutation is covered. The component test moves to goldengen.Component the same way.
Mutation-level unit tests are unchanged. Per-case golden files are replaced by
regime-based goldengen output.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Build resources through their real factory functions instead of re-spelling the
build inline, and assert the firing set via concepts.MutationInspector where a
resource registers mutations (component-prerequisites, custom-resource).
Extract BuildComponent helpers shared by the controller and a new component-level
test that goldens each example's distinctive component behavior (prerequisite
ordering, extraction feeding a guard, grace suppression).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Lead with the mutation/resource/component layering: unit-test a mutation against
a baseline, assert which mutations fire via concepts.MutationInspector, and pin
output with golden. Frame goldengen as the declarative coverage tool that works
at both resource (goldengen.Resource) and component (goldengen.Component)
granularity, with AssertComplete proving every registered mutation is tested.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Drop the manual MutationInspector/FiringSet introspection from the tutorial step;
a single golden assertion is the right altitude for getting started. The
firing-set introspection and goldengen coverage are covered on the Testing page,
which the step already links to.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Build the single-resource golden example through a factory instead of an inline
builder, define owner in every complete test snippet so they compile as written,
and fix the -update note whose content sat on the same line as the !!! note
directive (so it rendered as plain text).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Remove the standalone 'asserting which mutations fire' section that taught the
manual MutationInspector type-assert and FiringSet call; goldengen.Resource is
the supported way to assert firing and it adds completeness. Keep a short note in
the goldengen section explaining the MutationInspector primitive it is built on.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The goldengen intro named FiringSet before it was introduced (the section that
explained it was removed). Drop the parenthetical; the MutationInspector note
later in the section is now where the primitive is first presented.
AssertComplete is an accounting check (every registered mutation must be in a
Requires or Exclude); it never evaluates firing. The firing is verified by the
Requires assertions during Run. Spell out the division of labor, which is easy to
misread.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…mplete

A compact table makes the division clear: Requires/Forbids assert firing during
the sweep, AssertComplete asserts coverage on registration, and nothing fails
merely because a mutation fired without a matching Requires.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Put the opening paren on the call line, one argument per line, and the closing
paren on its own line with a trailing comma.
…ed deep copy

The YAML-loaded fixture spec is unmarshaled once at load time and reused for every
version in the sweep, so the build callback must deep-copy it before setting the
version, exactly like the Go Config.Build. newSpec is called once per fixture at
load time, not per build invocation.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Previously the LoadMatrix snippet referenced buildUnit by name only, hiding the
deep copy and version-setting the prose describes. Show the full function so the
shared-spec handling is visible.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Make the wiring explicit: LoadMatrix stores buildUnit as Config.Build and loads
fixtures from the file; goldengen.New + gen.Run then call buildUnit per version
and fixture. The YAML supplies the data, buildUnit supplies the build logic.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Driven by fresh-reader tests for a newcomer and an experienced author:

- Add an import block to the canonical golden example so it compiles, and name
  the test-helper package path; clarify that owner/resources/scheme are the
  reader's own packages and the package-level scheme.
- Explain why the factory result is type-asserted to golden.Previewer, and that
  a built component satisfies ComponentPreviewer directly (no assertion).
- Add a goldengen.Component Build example (component-level coverage), and explain
  that a component's registered/firing set is the deduplicated union of its
  resources' mutations.
- Show how to chain AssertComplete across multiple generators in one package.
- Cross-link buildComponent to Getting Started for building a component.
- Reword the LoadMatrix wiring ('runs like one declared in Go') and fix a wrong
  'defined below' reference.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The guideline showed a hand-written one-golden-per-version loop, which the testing
guide now supersedes with goldengen.Resource (firing regimes, gating assertions,
AssertComplete coverage). Reframe around goldengen, keep the baseline-safety
principle and the review-the-diff insight, and drop the manual loop. Retitle to
'Pin Rendered Output Across Supported Versions'.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…iagram

Replace the hand-drawn ASCII tree with a Mermaid flowchart (consistent with the
page's other diagrams and the README), and center Mermaid diagrams site-wide via
extra.css.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
sourcehawk and others added 5 commits June 2, 2026 04:53
…ner-reference caveat

Confirm that moving a resource from WithResource to IncludeWhen(false) drops it
from the component without deleting it, and warn that the controller owner
reference set while it was managed is not stripped, so Kubernetes still
garbage-collects it when the owner is deleted unless you remove the reference.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
A semicolon in the Note text terminated the Mermaid statement (Mermaid treats ;
as a separator), so the whole sequenceDiagram failed to parse. Replace it with a
comma.
Add OrphanWhen(cond) to the resource-options table, and replace the IncludeWhen
'remove the owner reference yourself' warning with a note recommending
OrphanWhen for releasing a resource so it outlives its owner. Include OrphanWhen
in the ReadOnly exclusivity list.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Cut the quick start, beyond-the-basics, primitives/lifecycle tables, and
custom-resource section (all now covered on the docs site). Keep the pitch, the
architecture diagram, one short taste, install, and a documentation section
linking to the published site and pkg.go.dev.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings June 2, 2026 03:03
Pull requests still build the site in strict mode to catch broken links and nav.
The site now deploys to GitHub Pages only when a release is published (so it
tracks the latest released version) or on manual workflow_dispatch, rather than
on every merge to the default branch.
Copy link
Copy Markdown

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR publishes the project documentation as a Material for MkDocs site on GitHub Pages and performs a broad documentation quality pass, while also updating examples/tests to align with the documented gating + golden-generation patterns.

Changes:

  • Adds MkDocs site configuration + tooling (mkdocs.yml, requirements-docs.txt, make docs-serve/docs-build) and a GitHub Pages workflow for strict builds + deploys.
  • Refactors multiple examples to use goldengen version-matrix generation and feature.NewBooleanGate, and adds component-level golden tests that share the same component assembly as controllers.
  • Rewrites/standardizes many primitive reference pages and core docs (index, compatibility, multiple primitives), including Mermaid diagrams and cross-linking to shared concepts.

Reviewed changes

Copilot reviewed 80 out of 89 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
requirements-docs.txt Pins MkDocs Material dependency for building docs.
mkdocs.yml Material for MkDocs site config: theme, extensions, nav structure.
Makefile Adds local docs serve/build targets.
.github/workflows/docs.yml Builds docs in --strict mode on PRs; deploys to Pages on main.
.gitignore Ignores MkDocs output directory (site/).
.tool-versions Adds Python toolchain entry for docs workflows/local dev.
docs/index.md New/updated docs landing page for the site.
docs/compatibility.md Expands compatibility policy and links to workflow/badge.
docs/stylesheets/extra.css Material theme CSS tweaks + Mermaid centering.
docs/primitives/statefulset.md StatefulSet primitive page rewritten/standardized.
docs/primitives/serviceaccount.md ServiceAccount primitive page rewritten/standardized.
docs/primitives/service.md Service primitive page rewritten/standardized.
docs/primitives/secret.md Secret primitive page rewritten/standardized.
docs/primitives/rolebinding.md RoleBinding primitive page rewritten/standardized.
docs/primitives/role.md Role primitive page rewritten/standardized.
docs/primitives/replicaset.md ReplicaSet primitive page rewritten/standardized.
docs/primitives/pvc.md PVC primitive page rewritten/standardized.
docs/primitives/pv.md PV primitive page rewritten/standardized.
docs/primitives/pod.md Pod primitive page rewritten/standardized.
docs/primitives/pdb.md PDB primitive page rewritten/standardized.
docs/primitives/networkpolicy.md NetworkPolicy primitive page rewritten/standardized.
docs/primitives/job.md Job primitive page rewritten/standardized.
docs/primitives/ingress.md Ingress primitive page rewritten/standardized.
docs/primitives/configmap.md ConfigMap primitive page rewritten/standardized.
docs/primitives/clusterrolebinding.md ClusterRoleBinding primitive page rewritten/standardized.
docs/primitives/clusterrole.md ClusterRole primitive page rewritten/standardized.
examples/version-matrix/version_matrix_test.go Updates version universe + expectations for the version-matrix example.
examples/version-matrix/resources/statefulset.go Renames/updates version-gated mutations to the new peer-discovery story.
examples/version-matrix/README.md Updates narrative/docs to match revised mutations and version set.
examples/version-matrix/testdata/version_matrix/manifest.yaml Updates goldengen manifest regimes for new versions/mutations.
examples/version-matrix/testdata/version_matrix/default/1.0.0.yaml Updates golden output for the pre-v2 regime.
examples/version-matrix/testdata/version_matrix/default/2.0.0.yaml Updates golden output for the v2 regime.
examples/mutations-and-gating/features/debug_logging.go Switches boolean gating to feature.NewBooleanGate.
examples/mutations-and-gating/features/tracing_sidecar.go Switches boolean gating to feature.NewBooleanGate.
examples/mutations-and-gating/features/metrics_config.go Removes version parameter; gates via feature.NewBooleanGate.
examples/mutations-and-gating/features/helpers_test.go Adds shared mutation-test baselines + no-op -update flag.
examples/mutations-and-gating/features/debug_logging_test.go Uses shared baseline helper for mutation-level testing.
examples/mutations-and-gating/features/tracing_sidecar_test.go Uses shared baseline helper for mutation-level testing.
examples/mutations-and-gating/features/metrics_config_test.go Uses shared baseline helper and updated mutation signature.
examples/mutations-and-gating/features/legacy_container_test.go Uses shared baseline helper for mutation-level testing.
examples/mutations-and-gating/resources/configmap.go Updates mutation signature usage.
examples/mutations-and-gating/resources/deployment_test.go Reworks resource tests to goldengen version-matrix + completeness accounting.
examples/mutations-and-gating/resources/configmap_test.go Adds goldengen version-matrix generation for ConfigMap and gating assertions.
examples/mutations-and-gating/resources/testdata/deployment/manifest.yaml Adds goldengen manifest for Deployment resource regimes.
examples/mutations-and-gating/resources/testdata/deployment/default/1.9.0.yaml Adds Deployment golden for v1 regime.
examples/mutations-and-gating/resources/testdata/deployment/default/2.0.0.yaml Adds Deployment golden for v2 regime.
examples/mutations-and-gating/resources/testdata/deployment/debug/1.9.0.yaml Adds debug fixture golden for v1 regime.
examples/mutations-and-gating/resources/testdata/deployment/debug/2.0.0.yaml Adds debug fixture golden for v2 regime.
examples/mutations-and-gating/resources/testdata/deployment/tracing/1.9.0.yaml Adds tracing fixture golden for v1 regime.
examples/mutations-and-gating/resources/testdata/deployment/tracing/2.0.0.yaml Adds tracing fixture golden for v2 regime.
examples/mutations-and-gating/resources/testdata/configmap/manifest.yaml Adds goldengen manifest for ConfigMap regimes.
examples/mutations-and-gating/resources/testdata/configmap/default/1.9.0.yaml Adds ConfigMap golden for default fixture.
examples/mutations-and-gating/resources/testdata/configmap/metrics/1.9.0.yaml Adds ConfigMap golden for metrics-on fixture.
examples/mutations-and-gating/README.md Updates docs to reference feature.NewBooleanGate.
examples/mutations-and-gating/app/controller.go Extracts component assembly into BuildComponent shared by controller + tests.
examples/mutations-and-gating/app/component_test.go Adds component-level goldengen matrix + completeness assertions.
examples/mutations-and-gating/app/testdata/component/manifest.yaml Adds goldengen manifest for component regimes.
examples/mutations-and-gating/app/testdata/component/all/1.9.0.yaml Adds component golden output (all features) for v1 regime.
examples/mutations-and-gating/app/testdata/component/all/2.0.0.yaml Adds component golden output (all features) for v2 regime.
examples/mutations-and-gating/app/testdata/component/minimal/1.9.0.yaml Adds component golden output (minimal) for v1 regime.
examples/mutations-and-gating/app/testdata/component/minimal/2.0.0.yaml Adds component golden output (minimal) for v2 regime.
examples/grace-inconsistency/resources/deployment_test.go Pins golden via resource factory (ensures factory behavior is tested).
examples/grace-inconsistency/app/controller.go Extracts component build into BuildComponent to share with tests.
examples/grace-inconsistency/app/component_test.go Adds component-level golden test for grace inconsistency example.
examples/grace-inconsistency/app/testdata/component.yaml Adds component golden YAML.
examples/extraction-and-guards/resources/configmap_test.go Pins golden via factory and wires shared extracted state.
examples/extraction-and-guards/resources/secret_test.go Pins golden via factory and wires shared extracted state.
examples/extraction-and-guards/app/controller.go Extracts component assembly into BuildComponent shared by controller + tests.
examples/extraction-and-guards/app/component_test.go Adds component-level golden test for extractor/guard example.
examples/extraction-and-guards/app/testdata/component.yaml Adds component golden YAML.
examples/custom-resource/resources/certificate_test.go Adds mutation registration/firing assertions via MutationInspector + keeps shape golden.
examples/component-prerequisites/resources/deployment_test.go Adds mutation registration/firing assertions; pins goldens via factory.
examples/component-prerequisites/resources/configmap_test.go Pins golden via factory.
examples/component-prerequisites/app/controller.go Extracts infra/app component builders for shared controller/test assembly.
examples/component-prerequisites/app/component_test.go Adds component-level golden tests for infra + app components.
examples/component-prerequisites/app/testdata/infra-component.yaml Adds infra component golden YAML.
examples/component-prerequisites/app/testdata/app-component.yaml Adds app component golden YAML.

Comment thread mkdocs.yml
Comment on lines +71 to +73
extra_css:
- stylesheets/extra.css

Comment on lines +10 to +13
pull_request:
workflow_dispatch:

permissions:
Comment on lines +46 to +53
with:
path: site

deploy:
name: Deploy to GitHub Pages
needs: build
if: github.event_name == 'release' || github.event_name == 'workflow_dispatch'
runs-on: ubuntu-latest
Make the top-level token read-only (inherited by the PR build job, which does
not need write scopes) and grant pages:write and id-token:write only to the
deploy job. Addresses the least-privilege review feedback.
@sourcehawk
Copy link
Copy Markdown
Owner Author

Thanks for the review. Resolution:

  • Permissions (docs.yml top-level + deploy job) — addressed. The top-level token is now read-only (inherited by the PR build job, which does not need write scopes), and pages: write / id-token: write are granted only to the deploy job. This is GitHub's standard Pages least-privilege pattern.

  • Mermaid runtime (mkdocs.yml) — no change needed. Material for MkDocs has native Mermaid support: when the pymdownx.superfences custom fence for mermaid is configured (as it is here), Material's own JS bundle loads the Mermaid runtime and initializes diagrams automatically, so no extra_javascript entry is required. Verified on the built site: the Material bundle contains the Mermaid loader and the diagrams render (the architecture, reconciliation-lifecycle, status-model, and plan-and-apply diagrams all draw correctly).

@sourcehawk sourcehawk merged commit 0ed5eee into main Jun 2, 2026
5 checks passed
@sourcehawk sourcehawk deleted the worktree-docs-github-pages branch June 2, 2026 03:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants