Skip to content

docs: move the manual to an mdBook site - #157

Merged
jonasz-lasut merged 6 commits into
mainfrom
docs/site
Oct 7, 2026
Merged

jonasz-lasut merged 6 commits into
mainfrom
docs/site

Conversation

@jonasz-lasut

@jonasz-lasut jonasz-lasut commented Oct 7, 2026 •

Copy link
Copy Markdown
Owner

The README had become the manual (1,350 lines, about 12,500 words), with every new capability landing as one more paragraph. This moves it to a documentation site on GitHub Pages, built with mdBook from docs/, and cuts the README down to a landing page. The sections move verbatim; a rewrite pass comes later.

Site: https://jonasz-lasut.github.io/function-wasm/ (live after the first push to main runs the deploy job).

Layout

book.toml at the root with src = "docs", so docs/abi-v2.md (named by the runtime's refusal sentence, the conformance goldens and code comments) and the one-pagers stay exactly where they are and are listed from there. docs/SUMMARY.md:

[Introduction](introduction.md)
- Use cases, How a request runs
# Guest authors
- Write a module, Other languages, Module manifests, Render locally, Validate a Composition
# Operators
- Install, Input reference, Runtime flags, Operator grant policy, HTTP egress,
  Readiness and warm-up, Sizing, Metrics, Trust model, Signatures, Troubleshooting
# Contract
- ABI v2 (docs/abi-v2.md), Compatibility
# Project
- Development, Security policy (SECURITY.md included in place), Use-case examples (the one-pager),
  Design records (an index page with each one-pager's status; every one-pager nested under it)

What moved where

README section page
the top (caution, what it is, the Composition example) docs/introduction.md
Use cases, Worked examples docs/use-cases.md
How a request runs docs/how-a-request-runs.md
Write a module docs/guests/write-a-module.md
Other languages docs/guests/other-languages.md
Module manifests (a subsection of Input reference) docs/guests/module-manifests.md
Render locally docs/guests/render-locally.md
Validate a Composition docs/guests/validate.md
Install docs/operators/install.md
Input reference docs/operators/input-reference.md
Runtime flags docs/operators/runtime-flags.md
Operator grant policy (the policy paragraphs) docs/operators/grant-policy.md
the readiness and warm-up paragraphs that sat under Operator grant policy docs/operators/readiness.md
HTTP egress (whole) docs/operators/http-egress.md
Sizing docs/operators/sizing.md
Metrics, gRPC server metrics docs/operators/metrics.md
Trust model (the model) docs/operators/trust-model.md
Trust model (the cosign paragraphs) docs/operators/signatures.md
AGENTS.md's Troubleshooting list docs/operators/troubleshooting.md
Compatibility, Deprecation policy docs/contract/compatibility.md
Development docs/project/development.md

Only heading levels, the links the move broke (README anchors, docs/ and examples/ paths) and a title or lead sentence where a page needed one changed; each page was diffed against its README range to prove it. Two cuts are at paragraph rather than subsection boundaries, because the paragraphs were misfiled under their headings: the readiness paragraphs out of "Operator grant policy", and the cosign paragraphs out of "Trust model" (the README's own links to them were named "signing"). "HTTP egress" stays whole under Operators: its three numbered parties are one narrative and splitting them would be a rewrite.

The README now

162 lines: the caution, three paragraphs on what function-wasm is and why with the Composition example, the Install snippet, a ten-line Write a module quick start, the scaffold table in its short form, a Documentation section listing every page of the site by absolute URL (so the landing page works from GitHub, mirrors and the Marketplace alike), and three lines of Development. Its one remaining section link (Compatibility, in the caution) points at the site.

Workflow and Pages

.github/workflows/docs.yml: on a pull request touching docs/**, book.toml, README.md or SECURITY.md, it builds the book with mdBook 0.5.4 (the release tarball, pinned by sha256 the way xprin and wkg are) and checks every internal link and anchor of the rendered site plus the README's relative links with lychee (lycheeverse/lychee-action v2.9.0, pinned by commit, --offline --include-fragments); on a push to main it also uploads the site and deploys it with actions/configure-pages, actions/upload-pages-artifact and actions/deploy-pages, all pinned by commit with the # vX.Y.Z comment Renovate reads. The job runs read-only; only the deploy job takes pages: write and id-token: write.

lychee over mdbook-linkcheck: mdbook-linkcheck has had no release since 2023 and targets mdBook 0.4's renderer API, which 0.5 replaced; lychee is maintained, checks fragments (--include-fragments, which is what catches a broken anchor after a move), and offline mode keeps the check deterministic. The 404 page is left out: it links by site-url-absolute paths that only exist once deployed.

Pages is enabled on the repository for the Actions source (gh api -X POST .../pages -f build_type=workflow returned build_type: workflow, html_url: https://jonasz-lasut.github.io/function-wasm/).

mdBook: the brief said the latest 0.4.x; 0.4's last release is from 2025 and 0.5 (November 2025) is the current line, so the book is built with 0.5.4 (June 2026). What 0.5 brought that the book uses: GitHub-style admonitions, so the README's [!CAUTION] block renders as one on the introduction page, and strict config checking, so a typo in book.toml fails the build. cargo install mdbook --locked --version 0.5.4 locally; the workflow uses the same version from the release tarball.

Theme

docs/theme/wasm.css, loaded through book.toml's additional-css, overrides the CSS variables of the built-in themes with WebAssembly's purple: #654FF0 on light backgrounds (default-theme = "light"), #8B74FF on dark ones (preferred-dark-theme = "navy"; coal and ayu take the same accent so switching themes keeps the colour). It colours links, the sidebar's active and hovered entries, the "on this page" border, inline code, blockquote borders, the search highlight, the search bar's focus ring and the theme menu's selection; body text and backgrounds stay the themes' own. Colours only, no logo: the WebAssembly logo is a trademark.

Re-pointed references

  • AGENTS.md: Key Reference Documents (README.md entry replaced by the docs/ pages), the Input reference pointer under Key Concepts, the Compatibility pointer under Conformance goldens, step 3 of Adding an Input Field, the Troubleshooting list (now a two-line pointer at docs/operators/troubleshooting.md), a new "Documentation site" subsection under Development Guide, and a book.toml, docs/SUMMARY.md entry in the Key Components tree.
  • One-pagers: resource-governance (the sizing table), sandbox (the flags table), language-support (the Other languages page, twice), module-source-schema (the first use case, twice), local-loop (the sizing table), nix-devenv (the "Building" section, five mentions, now the Development page), use-case-examples (the five ../examples/ links, now repository URLs).
  • docs/abi-v2.md: its link to wit/wasmfn-function.wit is a repository URL now (the rendered site cannot reach files outside docs/); the file's path and the refusal sentence are untouched.
  • crates/function/src/input.rs: the doc comment on API_VERSION_V1BETA1 names docs/contract/compatibility.md.
  • .claude/skills/cut-release/SKILL.md: the install snippet to bump is in README.md and docs/operators/install.md.
  • examples/dashboard-bundle/README.md: "as the function-wasm README shows" links the runtime flags page.
  • package/crossplane.yaml: the package readme annotation links the site and the repository.

Verified

  • mdbook build clean (no warnings); lychee offline over book/**/*.html and README.md with fragments: 1,562 links, 0 errors (303 excluded: the remote ones).
  • cargo fmt --all --check, cargo test -p guestfn (scaffold goldens untouched), cargo test -p function-wasm --test conformance (the refusal sentence still names docs/abi-v2.md at its path).
  • A final grep: no file links a README anchor that no longer exists; the remaining "Input reference" mentions in AGENTS.md name the new page.
  • Em dashes: 61 added lines carry one, every one of them a line moved verbatim from the README or AGENTS.md; no line written for this PR has one.

Follow-up: the rewrite pass

  • A guestfn reference page (init, build, push, inspect, manifest, scaffold composition): today those paragraphs sit inside "Write a module", which has no subsections to split along.
  • "HTTP egress" split into a guest-side page (the manifest rules, wasmfn.HTTPClient()) and the operator-side page (enablement, the block list, budgets, the audit line).
  • A Caches page: the on-disk stores are described across "Runtime flags" and "How a request runs"; nothing in the README stood on its own to move.
  • The introduction repeats the README's top; a rewritten landing page and a rewritten introduction should each say their own thing.
  • one-pager-nix-devenv.md and one-pager-language-support.md refer to a README "Building" section and a docs/abi.md that were already gone; the pointers now name the Development and Other languages pages, the prose around them is as it was.
  • A ## License line on the README, if wanted: the README never had one, so none was added.

Cedar policy reference (fifth commit)

Jonasz's preview found no Cedar policy documentation, so docs/operators/cedar-policy.md is new prose (the one page in this PR that is not a verbatim move), listed right after "Operator grant policy" and linked from the grant-policy page, the compositionPolicy row of the Input reference, the module manifests page and the dialAddress paragraph of HTTP egress. Every claim is taken from crates/function/src/authz.rs (the shared schema, the seven actions, COMPOSITION_ACTIONS, scopes_action, the dialAddress compiler and its load errors, the unit tests' example set), admission.rs and from.rs (the refusal sentences, quoted as printed and cross-checked against the conformance goldens), main.rs (the startup TMPDIR probe and the --cosign-key without requireSignature warning) and validate.rs (exit codes, warnings, the principal from --xr).

Headings: The two layers; The principal; Entity types; Actions; How each layer decides (the operator layer, the composition layer); Worked examples (one per action: pullModule, spendCredential, usePrivateTmp, setEnv, grantEgress, requireSignature, dialAddress); What a refusal says; Load-time errors; Testing a policy; Further reading.

One thing the code review turned up in the moved text: the HTTP egress page's dialAddress example ("Block an internal range, then open one service inside it": a forbid on 10.0.0.0/8 and a permit on 10.96.0.0/12) does not do what its comment says. Egress::blocked_by judges an operator forbid before the permit holes, so the service range stays blocked; the permit alone would open it, since the default block list already refuses 10.0.0.0/8. The Cedar page documents the real precedence with that shape as its worked example; the moved paragraph is left as it was, for the rewrite pass (or a one-line fix here if you prefer).

The manual moves to a documentation site on GitHub Pages
(https://jonasz-lasut.github.io/function-wasm/), built with mdBook
0.5.4 from docs/ itself: book.toml at the root with src = "docs", so
docs/abi-v2.md (named by the runtime's refusal sentence and the
conformance goldens) and the one-pagers stay at their paths and are
listed from where they are. docs/SUMMARY.md is the table of contents:
an introduction group, a Guest authors part, an Operators part, the
Contract (ABI v2, Compatibility) and the Project part, whose Design
records page lists every one-pager with its status and whose Security
policy page includes SECURITY.md in place.

docs/theme/wasm.css lays WebAssembly's purple over the built-in light
and navy themes through their CSS variables (#654FF0, #8B74FF on dark
backgrounds): links, the sidebar's active entry, inline code, blockquote
borders, the search highlight and the theme menu's selection; body text
and backgrounds stay the themes' own. Colours only, no logo.

.github/workflows/docs.yml builds the book on every pull request that
touches docs/, book.toml, README.md or SECURITY.md (mdBook from its
release tarball, pinned by sha256 like xprin and wkg) and checks every
internal link and anchor of the rendered site with lychee in offline
mode; a push to main uploads it and deploys with configure-pages,
upload-pages-artifact and deploy-pages, all pinned by commit.
Every section of the README is cut into its page verbatim: only the
heading levels (a section becomes its page's title), the links the move
breaks (README anchors, docs/ and examples/ paths) and a title or lead
sentence where a page needs one change. Introduction (the README's top),
Use cases and How a request runs; Write a module, Other languages,
Module manifests, Render locally and Validate a Composition for guest
authors; Install, Input reference, Runtime flags, Operator grant policy,
HTTP egress, Readiness and warm-up (the readiness paragraphs that sat
under the grant policy), Sizing, Metrics with the gRPC server series,
Trust model, Signatures (the cosign half of the trust model) and
Troubleshooting (AGENTS.md's list, verbatim) for operators;
Compatibility with the deprecation policy under Contract; Development
under Project. A rewrite pass comes later; nothing is reworded here.
The README keeps the caution, what function-wasm is and why, the
Install snippet, a ten-line Write a module quick start, the scaffold
table in its short form, a Documentation section listing the site's
pages by absolute URL (so the landing page works from GitHub, mirrors
and the Marketplace alike) and three lines of Development. Everything
else now lives on the site; the README's own anchors are gone, so its
one remaining section link (Compatibility, in the caution) points at
the site.
Every pointer into a README section moves to the page that holds it
now: AGENTS.md's Key Reference Documents, its Input reference and
Compatibility pointers and the Adding-an-Input-Field step name the
docs/ pages, its Troubleshooting list (moved verbatim to the operators'
page) becomes a two-line pointer, and a Documentation site paragraph
says where the book lives, how it is built and that user-facing
behaviour is documented in docs/ with the README as the landing page
only. The one-pagers' "the README's ..." mentions, input.rs's doc
comment on the deprecation policy, the cut-release skill's install
snippet list, dashboard-bundle's README and the package's readme
annotation follow. docs/abi-v2.md's link to the WIT file and the
use-case one-pager's example links become repository URLs, since the
rendered site cannot reach files outside docs/.
A reference page for both policy layers, docs/operators/cedar-policy.md,
listed after the operator grant policy and linked from that page, the
Input reference's compositionPolicy row, the module manifests page and
the dialAddress paragraph of HTTP egress: the two layers and how they
combine with the manifest, the principal and its attributes, the entity
types with their hierarchies, the seven actions with the layer, resource
and context each takes, the evaluation rules (the operator layer
default-deny with forbid winning, the composition layer default-deny for
the module.from fences and scoped default-permit for the sandbox
actions), one worked rule per action in the shape authz.rs's tests hold
it to, the refusal sentences per layer as admission.rs and from.rs print
them, the load-time errors of a dialAddress rule, the startup checks and
how function validate exercises a policy. Every claim is from the code;
the README never had this page.
@jonasz-lasut
jonasz-lasut merged commit cc1ffa9 into main Oct 7, 2026
5 checks passed
@jonasz-lasut
jonasz-lasut deleted the docs/site branch October 7, 2026 13:37
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.

1 participant