From 0fe066d42061584075584141ac8ebe82c650d5ac Mon Sep 17 00:00:00 2001 From: Bryan Helmkamp Date: Fri, 18 Sep 2026 19:24:34 -0400 Subject: [PATCH] Fix the rustdoc link warnings and gate rustdoc in CI Every intra-doc link `cargo doc --workspace --no-deps` warned on now resolves or is plain code: the private constant and helper, the removed `InterpString::resolve`, the lithos `Message`, the sandbox-driver facets, the `RunOptions::git_author` the cutover removed, and the stale `platform_record_for` paragraph on the platform records. The `[@REF]` segment of `fabro run`'s help text is allowed as help, not a link. A `Rustdoc` job runs the same command with `-D warnings`. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/rust.yml | 20 +++++++++++++++++++ lib/apps/fabro-cli/src/args.rs | 4 ++++ .../fabro-sandbox/src/driver_sandbox.rs | 7 ++++--- .../fabro-store/src/platform_records.rs | 9 ++++----- .../fabro-workflow/src/git_identity.rs | 2 +- lib/foundation/fabro-types/src/mcp_store.rs | 2 +- .../fabro-types/src/run_projection.rs | 3 ++- .../fabro-types/src/settings/interp.rs | 2 +- .../fabro-types/src/settings/run.rs | 6 +++--- lib/foundation/fabro-types/src/transcript.rs | 2 +- lib/foundation/fabro-util/src/text.rs | 2 +- 11 files changed, 42 insertions(+), 17 deletions(-) diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 53d09d5c1..b3f9451e3 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -91,6 +91,26 @@ jobs: fi - run: cargo +nightly-2026-04-14 clippy --locked --workspace --all-targets -- -D warnings + rustdoc: + name: Rustdoc + runs-on: ubuntu-24.04-x86-32-cores + permissions: + contents: read + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + - uses: dtolnay/rust-toolchain@631a55b12751854ce901bb631d5902ceb48146f7 # stable + with: + toolchain: 1.97.1 + - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 + with: + cache-on-failure: true + # Broken intra-doc links and the other rustdoc lints fail the build. + - run: cargo doc --locked --workspace --no-deps + env: + RUSTDOCFLAGS: -D warnings + generated-docs: name: Generated Docs runs-on: ubuntu-24.04-x86-32-cores diff --git a/lib/apps/fabro-cli/src/args.rs b/lib/apps/fabro-cli/src/args.rs index 02f211fce..747768bdc 100644 --- a/lib/apps/fabro-cli/src/args.rs +++ b/lib/apps/fabro-cli/src/args.rs @@ -234,6 +234,10 @@ pub(crate) struct RunArgs { pub(crate) inputs: InputOverrideArgs, /// Workflow name, path, or OWNER/REPO[@REF]:WORKFLOW + #[allow( + rustdoc::broken_intra_doc_links, + reason = "the help text's `[@REF]` is an optional segment, not a link" + )] #[arg(required = true)] pub(crate) workflow: Option, diff --git a/lib/components/fabro-sandbox/src/driver_sandbox.rs b/lib/components/fabro-sandbox/src/driver_sandbox.rs index 5e774f791..6328c53f5 100644 --- a/lib/components/fabro-sandbox/src/driver_sandbox.rs +++ b/lib/components/fabro-sandbox/src/driver_sandbox.rs @@ -1,8 +1,9 @@ -//! Fabro's [`Sandbox`] over a sandbox-driver handle. +//! Fabro's [`RunSandbox`] over a sandbox-driver handle. //! //! Every operation goes to a public driver facet: files through -//! [`Filesystem`], content and tree search through [`Search`], commands -//! through fabro's [`SandboxExec`] policy over the [`Exec`] facet, lifecycle +//! [`sandbox_driver::Filesystem`], content and tree search through +//! [`sandbox_driver::Search`], commands through fabro's [`SandboxExec`] +//! policy over the [`sandbox_driver::Exec`] facet, lifecycle //! through the handle itself. Nothing here knows which provider is behind //! the handle or whether it runs in-process or over the plugin wire. //! diff --git a/lib/components/fabro-store/src/platform_records.rs b/lib/components/fabro-store/src/platform_records.rs index 096cb8f58..d83ef9cbb 100644 --- a/lib/components/fabro-store/src/platform_records.rs +++ b/lib/components/fabro-store/src/platform_records.rs @@ -10,11 +10,10 @@ //! //! [`PlatformRecord`] is the one enum of record kinds, each with its typed //! payload, tagged by `kind` on the wire; [`PlatformRecordKind`] names the -//! kinds. The writer of a record is whoever performs the effect. The -//! lifecycle kinds are written by the run's create and lifecycle paths, which -//! today still append Fabro's legacy run events: for a Petri run the run -//! summary store derives the platform record from the legacy event through -//! [`platform_record_for`] and stores both in the event's transaction. The +//! kinds. The writer of a record is whoever performs the effect: the +//! `run.created` and `run.lifecycle` kinds by the run's create and lifecycle +//! paths (the server at create, the worker around the engine), through +//! [`PlatformRecordStore::append`] or the worker's client. The //! `run.branch`, `git.identity`, `checkpoint`, `artifact.collected`, //! `run.diff`, `pull_request.created`, `notification.sent` and `run.paired` //! kinds are defined here and written by the adapters that perform those diff --git a/lib/components/fabro-workflow/src/git_identity.rs b/lib/components/fabro-workflow/src/git_identity.rs index 0b5afb9bc..24c29573e 100644 --- a/lib/components/fabro-workflow/src/git_identity.rs +++ b/lib/components/fabro-workflow/src/git_identity.rs @@ -3,7 +3,7 @@ //! The run resolves its identity once, after its GitHub credentials are //! selected and before anything can commit, then uses it everywhere: engine //! checkpoints and metadata commits read it through -//! [`RunOptions::git_author`](crate::run_options::RunOptions::git_author), +//! [`git_author_from_settings`](crate::git::git_author_from_settings), //! and every workflow command, prepare step, native agent shell tool, and ACP //! agent launch receives it as the four `GIT_AUTHOR_*` / `GIT_COMMITTER_*` //! variables so plain `git commit` inside the sandbox agrees with the engine. diff --git a/lib/foundation/fabro-types/src/mcp_store.rs b/lib/foundation/fabro-types/src/mcp_store.rs index 5a7d64535..9f0f0b11b 100644 --- a/lib/foundation/fabro-types/src/mcp_store.rs +++ b/lib/foundation/fabro-types/src/mcp_store.rs @@ -6,7 +6,7 @@ //! crate, which persists `id` and a content-hash `revision` alongside the //! normalized definition fields. //! -//! Transport is the existing [`McpTransport`](crate::settings::McpTransport) +//! Transport is the existing [`McpTransport`] //! reused verbatim, so a stored definition uses the same `stdio`/`http`/ //! `sandbox` shape as inline MCP config. //! diff --git a/lib/foundation/fabro-types/src/run_projection.rs b/lib/foundation/fabro-types/src/run_projection.rs index fb0d06428..78ee66dfd 100644 --- a/lib/foundation/fabro-types/src/run_projection.rs +++ b/lib/foundation/fabro-types/src/run_projection.rs @@ -765,7 +765,8 @@ impl RunProjection { entries.into_iter() } - /// Mutable counterpart of [`iter_stages`]. Same chronological ordering. + /// Mutable counterpart of [`Self::iter_stages`]. Same chronological + /// ordering. pub fn iter_stages_mut(&mut self) -> impl Iterator { let mut entries: Vec<(&StageId, &mut StageProjection)> = self.stages.iter_mut().collect(); entries.sort_by(|(left_id, left_stage), (right_id, right_stage)| { diff --git a/lib/foundation/fabro-types/src/settings/interp.rs b/lib/foundation/fabro-types/src/settings/interp.rs index 44841401d..00613f29c 100644 --- a/lib/foundation/fabro-types/src/settings/interp.rs +++ b/lib/foundation/fabro-types/src/settings/interp.rs @@ -303,7 +303,7 @@ impl InterpString { /// /// This is a footgun for consumers: passing the raw source downstream /// leaks `{{ ... }}` tokens as literal text. Resolve via - /// [`InterpString::resolve`] / [`InterpString::resolve_with`] (or + /// [`InterpString::resolve_with`] (or /// substitute via [`InterpString::substitute_with`]) instead. Intentional /// uses — serialization, error messages, deliberate source preservation — /// must document themselves with diff --git a/lib/foundation/fabro-types/src/settings/run.rs b/lib/foundation/fabro-types/src/settings/run.rs index 9b8fd09c7..5faefc4cc 100644 --- a/lib/foundation/fabro-types/src/settings/run.rs +++ b/lib/foundation/fabro-types/src/settings/run.rs @@ -954,7 +954,7 @@ impl RunPrepareSettings { /// /// A missing or non-token secret is a hard error. Unsupported `env` and /// template-only `inputs` tokens surface as - /// [`ResolveErrorKind::Unavailable`] errors. + /// [`ResolveErrorKind::Unavailable`](super::interp::ResolveErrorKind::Unavailable) errors. pub fn resolve_step_secrets( &self, mut secrets_lookup: impl FnMut(&str) -> Option, @@ -1778,7 +1778,7 @@ impl McpServerSettings { /// Unsupported tokens fail instead of reaching the transport. /// /// This is the late, use-time half of MCP interpolation, the counterpart - /// to [`substitute_mcp_transport`]: `{{ vars.* }}` are substituted + /// to `substitute_mcp_transport`: `{{ vars.* }}` are substituted /// earlier, server-side, while `{{ secrets.* }}` resolves in whichever /// process actually launches the server (the run worker for `fabro run`, /// the CLI process for `fabro exec`). Carrying the source form out of the @@ -1786,7 +1786,7 @@ impl McpServerSettings { /// /// A missing or non-token secret is a hard error. Unsupported `env` and /// template-only `inputs` tokens surface as - /// [`ResolveErrorKind::Unavailable`] errors. + /// [`ResolveErrorKind::Unavailable`](super::interp::ResolveErrorKind::Unavailable) errors. pub fn resolve_transport_secrets( &self, mut secrets_lookup: impl FnMut(&str) -> Option, diff --git a/lib/foundation/fabro-types/src/transcript.rs b/lib/foundation/fabro-types/src/transcript.rs index ce278af48..c318db185 100644 --- a/lib/foundation/fabro-types/src/transcript.rs +++ b/lib/foundation/fabro-types/src/transcript.rs @@ -156,7 +156,7 @@ pub struct PairMessageRef { /// Canonical durable transcript message. /// /// Named `TranscriptMessage` rather than `Message` to avoid import ambiguity -/// with pebble's `Message` and the lithos request [`Message`]. +/// with pebble's `Message` and the lithos request `Message`. /// /// `kind` captures provider/model-role semantics for replay; `source` /// captures audit/UI provenance. Both are required to faithfully reconstruct diff --git a/lib/foundation/fabro-util/src/text.rs b/lib/foundation/fabro-util/src/text.rs index f492f7ce9..06db5caab 100644 --- a/lib/foundation/fabro-util/src/text.rs +++ b/lib/foundation/fabro-util/src/text.rs @@ -13,7 +13,7 @@ fn is_bidi_control(ch: char) -> bool { /// /// Strips ANSI escape sequences, then removes control and bidi-reordering /// characters, trims surrounding whitespace, and elides anything past -/// [`MAX_DISPLAY_LABEL`]. Any terminal-facing identifier built from runtime +/// `MAX_DISPLAY_LABEL`. Any terminal-facing identifier built from runtime /// data should go through this — without it a label can move the cursor, /// inject color, or reverse the text around it. ///