Documentation Site - #74
Merged
Merged
Conversation
The facade pages now explain each public type, constructor, method, argument, field, and variant for a host author. `lib.md` gives a short introduction to prompts, a first run, the host loop, the walk, determinism, concurrency, and a full reference for the root items. Each module page gives its place in the host loop, worked doctests, and a reference section. - Links to enum variant fields point at the re-exported enum with a field anchor, for example `(Event#variant.TaskAbandoned.field.reason)`. A direct link to the field resolves to the defining internal crate. - Doctest prompt sources use `concat!` with one string per line, because rustdoc hides doctest lines that start with `# `. - The pages state current gaps as facts: eight `Event` variants have no emit site, `Stat` and `Entry` have no public constructor for a custom `VfsAccess`, no `Flags` bit is defined, and `Environment::max_depth` is not read. - `cancel.md` now says that the engine shares one run flag with every section and does not create per-task child handles. - Only `.md` files under `crates/promptforge/src/` change. No Rust source or public signature changes.
Each product is getting its own self-contained documentation, with separate navigation and search, gathered under one site behind a landing page. This change adds the static pieces of that site: book configurations for the Gateway, Workshop, and Language guides, a shared script that puts an "All docs" link in each book's menu bar, a placeholder Workshop chapter, and a landing page that introduces the system and links to every product. Nothing in this change builds or publishes these files, and it modifies no existing file. - `guide/books/gateway/book.toml`: The Gateway, Workshop, and Language guides each get a separate mdBook config with its own title and a `site-url` under `/promptforge/`, so each guide is its own site with its own navigation and search. All three load the shared `back-link.js` through `additional-js`. - `guide/chrome/back-link.js`: One shared script adds the "All docs" link to every book's menu bar. It depends on two mdBook internals it does not declare: the `path_to_root` global and the `#menu-bar .right-buttons` markup. - `guide/landing/index.html`: The landing page is hand-written HTML with a title, tagline, and intro, then a four-row `products` table for PromptForge, Harness, Workshop, and Gateway. Its links fix the site layout at one folder per product, with the Prompt Language and Agent Programs guides as the `language/language/` and `language/agent/` sections of one book. - `addLink`: The link targets `path_to_root + "../index.html"`, a file one folder above the book root rather than a folder, so it also opens the landing page under `file://`. When the menu bar selector matches nothing, it logs a `console.warn` and adds no link. - `guide/landing/style.css`: The table splits text and image about 60/40 and stacks into one column below 800 pixels, and each image slot is a fixed 320 by 200 pixel dashed box. - `additional-js`: The configs name `back-link.js` and `src` relative to themselves, but this change adds the script under `guide/chrome/` and adds no `src` folder under `guide/books/`. Nothing in this change reads the configs or builds the books. - `promptforge/index.html`: Every landing link targets a per-product folder that this change does not build, and this change adds no link check. - `guide/src/workshop/01-stub.md`: The Workshop guide holds only a `# Coming Soon` heading. - `image-slot`: Every product row shows a dashed "image" placeholder whose comment names the intended file, such as `img/promptforge.png`, and `guide/landing/img/` holds only a `.gitkeep`. Design: new hidden-dependency @ guide/chrome/back-link.js::addLink Deferred: The Workshop guide ships only a placeholder heading Deferred: Each landing row shows a placeholder instead of its product image Plan: vibe/2026-09-25-2-multi-product-docs-site.md
The Harness API crate documentation now opens with a title kept in its own Markdown page, placed ahead of the existing crate overview and invariants, so the overview can later be written and maintained as a separate page. A new HTML fragment adds an "All docs" bar to rustdoc pages that links back to the site landing page. It finds the landing page relative to each page's documentation root, so the link works both from local files and under the hosted site prefix. The fragment is not yet passed to any rustdoc build.
- `#![doc = include_str!("lib.md")]` sits above the existing `//!` block, so rustdoc renders the `lib.md` text first, followed by the crate overview and its `## Invariants` section.
- `guide/chrome/banner.html` is one self-contained fragment of markup plus an inline script. It builds the link as `data-root-path` plus `../index.html`, which assumes every rustdoc tree sits one folder below the landing page, and it names `index.html` rather than the folder so the link also opens under `file://`.
- `place` runs on `DOMContentLoaded`, moves the bar to the top of `main`, and only then unhides it, because rustdoc lays out the body as a flex row and the bar would otherwise sit beside the content.
- `console.warn` is the only failure signal: when the `rustdoc-vars` meta tag has no `data-root-path`, or the page has no `main` element, the script logs a warning and removes the bar, and the page renders without it.
- `guide/chrome/banner.html` is not referenced by anything in this change, so no generated page carries the bar yet.
- `crates/harness-api/src/lib.md` holds only the `# Harness API` title.
Design: new hidden-dependency @ guide/chrome/banner.html
Design: new event-hook @ guide/chrome/banner.html::place
Deferred: The crate overview in crates/harness-api/src/lib.md has only its title.
Plan: vibe/2026-09-25-2-multi-product-docs-site.md
The guide assembler now takes its documentation sets from a single table of books, and the Workshop becomes a set of its own. Grouping sets by book prepares for each book being built as its own separate guide. Running the assembler with no arguments now only checks every set's chapters and writes one single-file export per set, including a new Workshop export. It no longer writes the shared table of contents or the per-part landing pages into the source tree, and it no longer needs the introduction page. The code that renders and link-checks those pages stays in place, used only by tests, until a staging mode renders them per book. - `BOOKS` replaces `SETS` as the only list of books and their sets, in audience order: Gateway, Workshop, then Language with the Prompt Language and Agent Programs sets. `sets` flattens it, and every loop over sets, including the test fixture, goes through it. - `assemble` no longer requires `introduction.md` and no longer writes `SUMMARY.md` or any set's `index.md`. The `[workshop.stt]` check and the H1 title check in `read_chapters` now cover the Workshop set too. - `assemble` renders every export in memory before writing any, so a failed check or unreadable chapter leaves all exports untouched. A write error partway through can still leave the earlier exports updated. - `stt_check_covers_every_set` plants a stale `[workshop.stt]` claim in each set in turn and expects the run to fail naming that file. `default_mode_writes_no_summary_or_index` checks that a run leaves no `SUMMARY.md` or `index.md` in the source tree. - `render_index`, `render_summary`, and `check_links` have no caller outside tests. Each carries a `dead_code` expectation in non-test builds, with the reason that tests exercise it until the stage mode renders books. - `sets` drops the book name from each `BOOKS` entry, so nothing in this change reads the book level of the table. - `guide/promptforge-workshop-guide.md` holds only the part title and a placeholder `# Coming Soon` heading. - `default_mode_runs_without_an_introduction` asserts nothing about the output. It checks only that `assemble` succeeds. Design: new pure-function @ crates/build-user-guide/src/main.rs::sets Plan: vibe/2026-09-25-2-multi-product-docs-site.md
The guide assembler gains a stage mode that copies the checked-in chapters into one mdBook source tree per book, under an output folder the caller names by absolute path. This lets each product's guide build as its own book while authors keep writing chapters where they do today. Each staged book gets its configuration, the shared script that adds an all-docs link, its chapter folders, a rendered overview page per part, and a table of contents that opens on the first part's overview instead of an introduction. Staging runs the chapter title and legacy speech-to-text checks before it writes anything, link-checks each book's table of contents after writing it, and only reads the checked-in guide tree. - `main` now dispatches on its arguments. No arguments runs the existing checks and exports, `stage <out>` runs staging, and anything else exits with a usage error that echoes the arguments it got. - `stage.rs` holds the staging code, with its tests in `stage-tests.rs` wired through `#[path]`. It imports `AssembleError`, `BOOKS`, and six private helpers from the crate root, and the root calls `stage::stage`, so the two modules depend on each other. - `render_index`, `render_summary`, and `check_links` drop their test-only `dead_code` expectations, because staging now calls all three. - `render_summary` no longer emits an `Introduction` entry, so each book's SUMMARY opens on its first set's `index.md`. The existing summary test now asserts that no `introduction.md` link appears. - `stage` rejects a relative output path with a message naming the path, before it creates anything. It then runs `check_removed_workshop_stt_claims`, which reads every set's chapters, so a stale `[workshop.stt]` claim, a missing set folder, or a chapter without an H1 title fails with the output folder untouched. - `copy_dir` copies every file in a set folder, including images in subfolders and any checked-in `index.md`, which the rendered overview then overwrites. - `check_links` runs after the book's `SUMMARY.md` is on disk, so a broken link leaves that book and every earlier book staged, and the error names the book. Every rendered target is a file staging just wrote or copied, so the check fails only when a chapter's title or file name breaks the link syntax, as the test's `02-proxy (draft).md` does. - `stage_writes_one_tree_per_book` checks each book's config, script, overview titles, SUMMARY links, and that its `src` holds only its own sets. `staging_is_deterministic` compares two fresh folders and a restage into a used one, and `stage_leaves_the_guide_tree_untouched` compares the guide tree byte for byte. - `stage` overwrites files already in the output folder but never removes any, so a reused folder keeps pages for chapters the guide has since dropped. - `main` has no test for its argument dispatch or usage error; the stage tests call `stage` directly. Design: new surface-growth @ crates/build-user-guide/src/main.rs::main boundary: pub Design: new cyclic-dependency @ crates/build-user-guide/src/stage.rs Plan: vibe/2026-09-25-2-multi-product-docs-site.md
The workspace automation tool gains a site command that assembles the documentation site into one folder. It clears the previous output, has the guide assembler stage one source tree per book, builds each staged book with mdBook, and copies the hand-written landing page on top. It then checks that every local link on the landing page names a file in the site and fails with the full list of broken links otherwise. The command does not build the API reference folders yet, so the check skips links into them, and the books-only flag only changes a printed note. - `build-user-guide` runs its stage mode as a child `cargo run` process instead of a library call, so this crate still depends on no workspace crates. Every path the command hands a child process starts from the workspace root, so each one is absolute. - `staged_books` takes the book list from the folders that staging wrote, sorted by name, so this crate names no book. It skips plain files and fails, naming the folder, when it finds no book folder. - `hrefs` finds links by splitting the page on the literal text `href="`, with no HTML parser. It misses single-quoted and spaced attributes. - `MDBOOK` and `CARGO` name the programs `build` runs, with `mdbook` and `cargo` as the fallbacks when they are unset. - `check_landing` receives `true` for `skip_rustdoc` on every call from `build`, so the check never looks at links into `promptforge/` or `harness/`. `--books-only` only decides whether `build` prints a note that the site holds the books only. - `unresolved` passes a link only when it names an existing file under the site folder after dropping any `#` fragment or `?` query. A leading `/`, a colon or backslash, a `..` segment, a folder, and a missing file each fail with their own reason, and the error lists every broken link in page order. - `copy_dir` recurses into subfolders, overwrites files that already exist, and removes nothing, so the landing page lands on top of the built books. - `run_child` stops the build when a child cannot start or exits unsuccessfully, and its message shows the full command line. - `parse_args` refuses anything but no arguments or a single `--books-only` and returns the site usage line. `run` then exits with status 1, while the top-level `usage` exits with status 2. - `site-tests.rs` covers argument parsing, book discovery, the copy helper, both child failures, and the link check for missing files, folders, links that leave the site, ignored prefixes, and the rustdoc skip. `a_child_that_exits_nonzero_is_named` spawns the real `cargo` with an unknown flag. - `build`, `run`, `check_landing`, and `clear` have no tests, so no test runs staging, mdBook, or the whole pipeline. Design: extends dispatch-on-tag @ crates/build-xtask/src/main.rs::main Design: new value-object @ crates/build-xtask/src/site.rs::Options Design: new pure-function @ crates/build-xtask/src/site.rs::parse_args deps: String Design: new hidden-dependency @ crates/build-xtask/src/site.rs::build deps: Options,Path Design: new flag-parameter @ crates/build-xtask/src/site.rs::check_landing deps: Path,bool Design: new flag-parameter @ crates/build-xtask/src/site.rs::broken_links deps: Path,bool,str Design: new pure-function @ crates/build-xtask/src/site.rs::hrefs deps: str Design: new pure-function @ crates/build-xtask/src/site.rs::first_segment deps: str Plan: vibe/2026-09-25-2-multi-product-docs-site.md
The site command now builds the API reference sites for PromptForge and Harness after the books, unless a books-only build is requested. Both crates are documented through one dedicated build folder that is cleared before each crate, so the two reference sites never share a crate list or search index and the developer's usual documentation output stays untouched. Every reference page carries the shared navigation banner, and each reference site folder gets a redirect page to its crate. The landing link check now covers links into the reference sites whenever they are built. - `build_rustdoc` documents each crate in `RUSTDOC_SITES` into the one `target/site-doc` folder and runs `cargo clean --doc` before each `cargo doc`, because rustdoc merges every crate in a doc folder into one crate list and search index. The developer's `target/doc` is never written. - `RUSTDOC_SITES` replaces `RUSTDOC_DIRS` and pairs each site folder with the crate it documents, `harness` with `harness-api`, as a tuple of bare strings. `broken_links` reads the folder half of the same table. - `encoded_rustdoc_flags` injects `guide/chrome/banner.html` through `CARGO_ENCODED_RUSTDOCFLAGS`, which cargo splits only on the `0x1f` separator, so a checkout path with spaces stays one argument where `RUSTDOCFLAGS` would split it. - `check_landing` now receives `options.books_only` instead of `true`, so a full build fails when a landing link into `promptforge/` or `harness/` does not resolve. Only `--books-only` still skips those links. - `redirect_page` writes each rustdoc site folder's `index.html` as a meta refresh plus a single link to the page `crate_page` names, such as `harness_api/index.html` for `harness-api`. - `crates/build-xtask/src/site-tests.rs` adds tests that pin the flag encoding against a drive path with spaces, the underscored crate page, and that the redirect's only `href` is the crate page. - `build_rustdoc` has no test in this change. The new tests cover only the three pure helpers. Design: new stringly-typed @ crates/build-xtask/src/site.rs::RUSTDOC_SITES Design: new pure-function @ crates/build-xtask/src/site.rs::encoded_rustdoc_flags deps: Path Design: new pure-function @ crates/build-xtask/src/site.rs::crate_page deps: str Design: new pure-function @ crates/build-xtask/src/site.rs::redirect_page deps: str Plan: vibe/2026-09-25-2-multi-product-docs-site.md
GitHub Pages now receives the assembled documentation site, with the landing page, the product books, and the API references, in place of the single combined guide. Pushes to the main branches and manual dispatches build the full site and deploy it. Pull requests that touch the docs sources, the site builder, or the workflow itself run a lighter build of the books and the landing page that never uploads or deploys, and other pull requests do not trigger it. Only the deploy job holds the Pages write permissions, and the old guide workflow goes away so two workflows never publish the same site.
- `github.event_name` selects the path inside one workflow. Pull requests run the books-only build, while pushes and manual dispatches run the full build, the artifact upload, and the deploy job.
- `contents: read` is the only workflow-wide permission. `pages: write` and `id-token: write` sit on the deploy job alone, and `actions/configure-pages@v5` moves into that job with them.
- `site-pr-{0}` gives each pull request ref its own concurrency group, and a new push cancels the stale run. Deploys share the `pages` group and never cancel one another.
- `cargo xtask site` builds the full site with `MDBOOK` pointing at the downloaded mdBook 0.4.44 binary. The upload now takes `target/site` instead of `guide/book`.
- `dtolnay/rust-toolchain` and `Swatinem/rust-cache` join the build job, each pinned to a commit SHA, because cargo now drives the build.
- `pull_request` fires only for changes under `guide/**`, `crates/build-user-guide/**`, `crates/build-xtask/src/site.rs`, or the workflow file itself.
- `--books-only` makes pull request runs skip the API reference builds. Those runs also never upload an artifact or reach the deploy job.
- `github.repository` guards both jobs, so forks run nothing.
- `.github/workflows/guide.yml` no longer exists, and its direct `./mdbook build guide` deploy of `guide/book` goes with it.
Design: new dispatch-on-tag @ .github/workflows/site.yml
Plan: vibe/2026-09-25-2-multi-product-docs-site.md
The guide now builds as separate books on the assembled docs site, so the single combined guide is retired. Its book configuration, shared table of contents, and per-set index pages leave the source tree, since the assembler now writes that navigation only into the staged books. The build instructions for contributors and agents now name the site command, because the old combined build has no book left to build. The two facade crates now link their documentation to their own API reference pages instead of the site root. - `guide/book.toml` is removed along with `guide/src/SUMMARY.md` and the checked-in `index.md` pages for the `gateway`, `language`, and `agent` sets. The source tree no longer holds the combined book's config or its generated navigation. - `.gitignore` drops the `/guide/book/` entry, which was the combined book's output folder. - `guide/CONTRIBUTING.md` now says the assembler writes each book's `SUMMARY.md` and per-part index files only into the staged books under `target/site-books/`, and that they must not be added to `src/`. It also lists four documentation sets, adding `src/workshop/`, and names `site.yml` as the deploy workflow. - `cargo xtask site --books-only` replaces `mdbook build guide` as the guide build command in `README.md` and `AGENTS.md`, and replaces the `cargo run -p build-user-guide` regenerate instruction in `guide/CONTRIBUTING.md`. - `documentation` in `crates/promptforge/Cargo.toml` and `crates/harness-api/Cargo.toml` now points at each crate's own rustdoc index page, `promptforge/promptforge/index.html` and `harness/harness_api/index.html`, instead of the site root. - `crates/README.md` now describes `build-user-guide` as checking the chapters and writing the per-set exports by default, with a `stage <out>` mode that writes one mdBook tree per book for `cargo xtask site`. Plan: vibe/2026-09-25-2-multi-product-docs-site.md
Plan: vibe/2026-09-25-2-multi-product-docs-site.md
This branch was successfully deployed
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.
This completely revises the structure of the documentation into a multi-documentation-site package.