From 621f712eacc3ca04e5021d033c01a9fc2716fc0c Mon Sep 17 00:00:00 2001 From: Mac Anderson Date: Sat, 8 Aug 2026 14:38:22 -0700 Subject: [PATCH] fix(gate): doc-warnings documents private items, so pub(crate) doc links are checked MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Rustdoc only checks intra-doc links inside items it documents, so the doc-warnings gate step — cargo doc --no-deps with -D warnings — was blind to every broken link in a private module, private function, or pub(crate) item. Adding --document-private-items surfaced 34 broken references across nine crates, all pre-existing on main: paths that do not resolve from their scope, links to renamed or deleted items (render_transcript, RepoBackend::push, fetch_url, RESUME_GRACE, BlockDraft::without_local_content), links into #[cfg(test)] modules that can never resolve in a doc build, and prose like argv[0] or sha256: that rustdoc parses as links or HTML. Every site is repaired in this commit — a resolving target where one exists (rustdoc resolves links with normal visibility rules from the linking scope, so only pub(crate)-or-wider targets are linkable across modules), prose with backticks where none can (test modules, fully-private items in sibling modules). The accept.rs twins stay byte-identical for their drift test. The flag flips in the same commit in all three normative homes (Makefile doc-warnings, ci.yml, CONTRIBUTING.md), so main never sees a red window between repairs and enforcement. --keep-going rides along on the same command: rustdoc bails at the first failing crate, which has repeatedly masked the next layer's break (#1823); with it the gate reports every crate in one run. Closes #2336 --- .github/workflows/ci.yml | 7 +++++-- CONTRIBUTING.md | 2 +- Makefile | 4 ++-- crates/stella-context/src/ann.rs | 2 +- crates/stella-context/src/candidates.rs | 4 ++-- crates/stella-context/src/retrieval.rs | 2 +- crates/stella-context/src/retrieval/ranking.rs | 6 +++--- crates/stella-context/src/store/domain.rs | 2 +- crates/stella-context/src/store/schema.rs | 2 +- crates/stella-core/src/driver.rs | 4 ++-- crates/stella-core/src/driver/loop_evidence.rs | 4 ++-- crates/stella-core/src/receipts.rs | 4 ++-- crates/stella-core/src/step.rs | 2 +- crates/stella-diag/src/dx.rs | 2 +- crates/stella-diag/src/redact.rs | 2 +- crates/stella-graph/src/generated.rs | 4 ++-- crates/stella-observatory/src/accept.rs | 2 +- crates/stella-serve/src/accept.rs | 2 +- crates/stella-serve/src/lifecycle.rs | 2 +- crates/stella-serve/src/server.rs | 6 +++--- crates/stella-serve/src/session.rs | 2 +- crates/stella-store/src/lib.rs | 2 +- crates/stella-store/src/reconstruct.rs | 4 ++-- crates/stella-tools/src/authored_diff.rs | 2 +- crates/stella-tools/src/bash.rs | 2 +- crates/stella-tools/src/project.rs | 2 +- crates/stella-tools/src/registry.rs | 2 +- crates/stella-tools/src/repo.rs | 2 +- crates/stella-tools/src/web.rs | 2 +- crates/stella-tui/src/deck_ui.rs | 2 +- crates/stella-tui/src/deck_ui/create.rs | 5 +++-- crates/stella-tui/src/render.rs | 4 ++-- crates/stella-tui/src/render/row.rs | 2 +- 33 files changed, 51 insertions(+), 47 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index db507c2ab..3770c7b0f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -404,10 +404,13 @@ jobs: # Nothing gated rustdoc, so its warning count only grew — one crate's doc # link to a private fn had made `cargo doc` a hard failure, unnoticed - # (#634). Gating is what stops it regrowing. + # (#634). Gating is what stops it regrowing. `--document-private-items` + # because rustdoc only checks links in items it documents, so without it + # every broken link in a private or pub(crate) item is invisible (#2336); + # `--keep-going` so one failing crate cannot mask the ones behind it. - name: cargo doc -D warnings if: ${{ !cancelled() && steps.rust.outcome == 'success' }} - run: RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps + run: RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --document-private-items --keep-going # Prompt caching has no stale-read failure mode: a hit and a miss return # the same tokens, so a broken cache never fails a test that asserts on diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index bd9a0aea1..93926c6b6 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -87,7 +87,7 @@ python3 ./scripts/check-doc-links.py check ./scripts/check-stat-portability.sh python3 ./scripts/check-module-reachability.py ./scripts/check-wire-schema.sh -RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps +RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps --document-private-items --keep-going cargo fmt --check cargo clippy --workspace --all-targets -- -D warnings cargo test --workspace diff --git a/Makefile b/Makefile index d8afc8d21..f72541a4d 100644 --- a/Makefile +++ b/Makefile @@ -216,8 +216,8 @@ file-size-update: ## Retighten the 1500-line ratchet baseline (run after splitti @./scripts/check-file-size.sh --update .PHONY: doc-warnings -doc-warnings: ## Assert rustdoc is clean workspace-wide (#634; CARGO_SCOPE to narrow) - RUSTDOCFLAGS="-D warnings" cargo doc $(CARGO_SCOPE) --no-deps +doc-warnings: ## Assert rustdoc is clean workspace-wide, private items included (#634, #2336; CARGO_SCOPE to narrow) + RUSTDOCFLAGS="-D warnings" cargo doc $(CARGO_SCOPE) --no-deps --document-private-items --keep-going .PHONY: shellcheck shellcheck: ## Lint install.sh, scripts/*.sh, and .githooks/* (#916) diff --git a/crates/stella-context/src/ann.rs b/crates/stella-context/src/ann.rs index fa54fcdb4..23ff8b31b 100644 --- a/crates/stella-context/src/ann.rs +++ b/crates/stella-context/src/ann.rs @@ -20,7 +20,7 @@ //! //! With an IVF the postings are ordinary rows and liveness stays exactly where //! it already lives: the `JOIN node` under the shared -//! [`NODE_AS_OF`](crate::candidates::NODE_AS_OF) predicate. So supersede, +//! [`NODE_AS_OF`] predicate. So supersede, //! restore, and point-in-time recall need **zero index maintenance** — pinned by //! `forgetting_a_node_needs_no_reindex` and //! `a_point_in_time_probe_needs_no_reindex`. A graph index would need an diff --git a/crates/stella-context/src/candidates.rs b/crates/stella-context/src/candidates.rs index f94874919..e706fc52d 100644 --- a/crates/stella-context/src/candidates.rs +++ b/crates/stella-context/src/candidates.rs @@ -310,12 +310,12 @@ pub(crate) fn vectors_for_ids( } /// Domain names for `ids` only, sorted per node — the bounded form of -/// [`domains_by_node`]. +/// [`domains_by_node`](crate::store::domains_by_node). /// /// An unscoped recall needs domains for exactly the frames it mints (they ride /// provenance so a citation view can show them), which is at most /// `max_frames × mmr_candidate_multiple` nodes. It was calling -/// [`domains_by_node`] instead — a full `node_domains ⋈ domain ⋈ node` scan +/// [`domains_by_node`](crate::store::domains_by_node) instead — a full `node_domains ⋈ domain ⋈ node` scan /// building a `HashMap` entry per tagged node in the workspace — and then /// looking up 20 of them. A domain-*scoped* recall still needs the whole map, /// because the overlap ranking in step 3b scores every node. diff --git a/crates/stella-context/src/retrieval.rs b/crates/stella-context/src/retrieval.rs index 392e20e9d..98a104216 100644 --- a/crates/stella-context/src/retrieval.rs +++ b/crates/stella-context/src/retrieval.rs @@ -16,7 +16,7 @@ //! someone. The IVF accelerator in [`crate::ann`] is opt-in through //! [`RecallTuning::ann_enabled`] and announces itself on //! [`RecallResult::used_ann_index`] when it fires. They are property-tested in -//! [`tests`]. +//! `tests` (a `#[cfg(test)]` module, so rustdoc cannot link it). use std::collections::{HashMap, HashSet}; diff --git a/crates/stella-context/src/retrieval/ranking.rs b/crates/stella-context/src/retrieval/ranking.rs index c2931b7ec..b97d866c6 100644 --- a/crates/stella-context/src/retrieval/ranking.rs +++ b/crates/stella-context/src/retrieval/ranking.rs @@ -97,7 +97,7 @@ pub(crate) fn coverage_score(cos_sorted: &[(i64, f32)], topk: usize) -> f32 { /// scores 1/61 and rank 100 scores 1/161 — barely a 2.6× spread across the /// whole corpus. A list added at weight 1.0 is therefore not a hint, it is a /// peer that can single-handedly decide the top of the result. See -/// [`DEFAULT_RECENCY_WEIGHT`]. +/// [`DEFAULT_RECENCY_WEIGHT`](crate::retrieval::DEFAULT_RECENCY_WEIGHT). pub(crate) fn rrf_fuse(lists: &[(Vec, f64)], k: f64) -> HashMap { let mut scores: HashMap = HashMap::new(); for (list, weight) in lists { @@ -181,7 +181,7 @@ pub(crate) struct MmrItem<'a> { /// `Θ(n³)` cosines. /// /// This pass is `Θ(n²)` in the candidates handed to it, which is why the caller -/// bounds them to [`DEFAULT_MMR_CANDIDATE_MULTIPLE`] x `max_frames` first. It used to be +/// bounds them to [`DEFAULT_MMR_CANDIDATE_MULTIPLE`](crate::retrieval::DEFAULT_MMR_CANDIDATE_MULTIPLE) x `max_frames` first. It used to be /// fed *every live node* — the recency ranking contributes all of them — so /// recall was quadratic in lifetime memory size and ran to exhaustion selecting /// candidates the budget pass then threw away. @@ -225,7 +225,7 @@ pub(crate) fn mmr_select(items: &[MmrItem<'_>], lambda: f32) -> Vec { /// so a smaller later frame can still fit. /// /// **Required items are admitted first** — Phase 2 (#713) deliverable 5. -/// [`SelectionReason::is_required`] marks a candidate the caller asked for by +/// [`SelectionReason::is_required`](crate::retrieval::SelectionReason::is_required) marks a candidate the caller asked for by /// name (today: a goal that names a file verbatim), and ADR 0006 says ranking /// may not evict one. A required item is therefore charged against the token /// budget before any ranked candidate competes for it, and **`max_frames` diff --git a/crates/stella-context/src/store/domain.rs b/crates/stella-context/src/store/domain.rs index f9d109c1e..21dc3bde5 100644 --- a/crates/stella-context/src/store/domain.rs +++ b/crates/stella-context/src/store/domain.rs @@ -78,7 +78,7 @@ pub(crate) fn tag_edge_domains( /// citation display — the batched form of the old per-node query. Recall /// runs this once per prompt; one statement per live node was an N+1 whose /// cost grew with lifetime memory size. Superseded nodes are filtered in -/// SQL (same liveness predicate as [`live_node_metas`]): recall only looks up +/// SQL (same liveness predicate as [`live_node_metas`](crate::candidates::live_node_metas)): recall only looks up /// live candidates, so loading dead nodes' tags made the scan grow with /// historical store size for no reader. pub(crate) fn domains_by_node( diff --git a/crates/stella-context/src/store/schema.rs b/crates/stella-context/src/store/schema.rs index 2cfabb936..c5216a311 100644 --- a/crates/stella-context/src/store/schema.rs +++ b/crates/stella-context/src/store/schema.rs @@ -156,7 +156,7 @@ DROP TABLE IF EXISTS code_graph_files; /// key and SQLite could only answer it by scanning the whole clustered index — /// every blob of every fingerprint, including the stale rows a fingerprint bump /// leaves behind. Recall runs exactly that predicate on every turn -/// ([`score_nodes_by_vector`]), so the scan was proportional to the store's +/// ([`score_nodes_by_vector`](crate::candidates::score_nodes_by_vector)), so the scan was proportional to the store's /// lifetime embedding count rather than to the active fingerprint's. /// /// `IF NOT EXISTS` because the index is also created by a fresh v4 store that diff --git a/crates/stella-core/src/driver.rs b/crates/stella-core/src/driver.rs index eefac9253..53179776f 100644 --- a/crates/stella-core/src/driver.rs +++ b/crates/stella-core/src/driver.rs @@ -2185,7 +2185,7 @@ impl<'a> Engine<'a> { /// no-tool shape that does NOT finish the turn (up to /// `driver::truncation::MAX_LENGTH_CONTINUATIONS` times): the model was /// cut off, not done, so the step is recorded and the turn continues with - /// [`LENGTH_CONTINUATION_NUDGE`]. `length_continuations` is the turn's + /// [`LENGTH_CONTINUATION_NUDGE`](truncation::LENGTH_CONTINUATION_NUDGE). `length_continuations` is the turn's /// running count ([`TurnState`]'s, threaded rather than owned so the /// bound survives across steps). async fn dispatch_completion( @@ -2551,7 +2551,7 @@ type SpeculationFuture<'a> = Pin + 'a>> /// Prefix of the overflow summarizer's marker message /// ([`Engine::summarize_overflow_span`]). Shared with -/// [`recent_call_records`]: the marker is User-role on the wire, but it is +/// [`recent_call_records`](loop_evidence::recent_call_records): the marker is User-role on the wire, but it is /// NOT a real user turn and must not act as a loop-detection window /// boundary. pub(crate) const SUMMARY_MARKER_PREFIX: &str = "[earlier history summarized"; diff --git a/crates/stella-core/src/driver/loop_evidence.rs b/crates/stella-core/src/driver/loop_evidence.rs index 74ffd8114..9781dec03 100644 --- a/crates/stella-core/src/driver/loop_evidence.rs +++ b/crates/stella-core/src/driver/loop_evidence.rs @@ -126,13 +126,13 @@ pub(super) fn recent_call_records<'a>( /// construction on two real providers — poisoning the id on the first step /// whose first call differs, and keeping it poisoned for the rest of the turn. /// -/// Name and input are exactly the fields [`loop_detect::same_record`] already +/// Name and input are exactly the fields `loop_detect::same_record` already /// requires to match before two records are "the same", so widening the key /// with them cannot merge two calls the detector would have distinguished. It /// only stops two UNRELATED calls that happened to share an ordinal from being /// treated as one. /// -/// Deliberately not positional: [`Engine::apply_overflow_summary`] splices a +/// Deliberately not positional: [`Engine::apply_overflow_summary`](super::Engine::apply_overflow_summary) splices a /// span of messages down to a single summary, so any index-derived key would /// silently re-point surviving results at another call's evidence after the /// first overflow — a WRONG identity, which is far worse than none. diff --git a/crates/stella-core/src/receipts.rs b/crates/stella-core/src/receipts.rs index d4168361a..9a7149174 100644 --- a/crates/stella-core/src/receipts.rs +++ b/crates/stella-core/src/receipts.rs @@ -198,8 +198,8 @@ fn zone_tag(zone: CacheZone) -> &'static str { /// workspace path — and that metadata is the preimage. The base64 payload /// exists only after the model layer hydrates a request, which happens below /// this point and never on the messages a receipt sees. A hydrated attachment -/// that somehow reached here is stripped by -/// [`BlockDraft::without_local_content`] rather than journaled. +/// that somehow reached here is dropped from the preimage rather than +/// journaled: decomposition maps `AttachmentSource::Data` to no local content. fn is_gap_kind(kind: BlockKind) -> bool { matches!( kind, diff --git a/crates/stella-core/src/step.rs b/crates/stella-core/src/step.rs index ee17148a0..f60aa85cb 100644 --- a/crates/stella-core/src/step.rs +++ b/crates/stella-core/src/step.rs @@ -1006,7 +1006,7 @@ where } } -/// Drop guard for the paid-call window ([`Engine::run_model_call`]): armed +/// Drop guard for the paid-call window ([`Engine`](crate::driver::Engine)'s `run_model_call`): armed /// before the retried provider dispatch, disarmed on both normal exits. It /// fires only when the turn future is dropped mid-await — the caller-side /// hard cancel — AND a paid attempt was genuinely in flight diff --git a/crates/stella-diag/src/dx.rs b/crates/stella-diag/src/dx.rs index 1644fba5e..8951bda2f 100644 --- a/crates/stella-diag/src/dx.rs +++ b/crates/stella-diag/src/dx.rs @@ -249,7 +249,7 @@ macro_rules! __diag_level { /// ``` /// /// `target` is `module_path!()` at the call site, which is what -/// [`Filter`](crate::Filter) matches on — so `STELLA_LOG=stella_store=debug` +/// [`Filter`] matches on — so `STELLA_LOG=stella_store=debug` /// selects records by where they were written, with no bookkeeping at the emit /// site. /// diff --git a/crates/stella-diag/src/redact.rs b/crates/stella-diag/src/redact.rs index 5a8663556..f4a1df84c 100644 --- a/crates/stella-diag/src/redact.rs +++ b/crates/stella-diag/src/redact.rs @@ -21,7 +21,7 @@ //! //! Three properties make this a hatch rather than a loophole: //! -//! 1. [`note!`] accepts **only a string literal**, so the justification lives +//! 1. [`note!`](crate::note) accepts **only a string literal**, so the justification lives //! in the source, is greppable, and shows up in the diff that introduced it. //! A `format!` or a variable does not compile. //! 2. The justification travels *into the record*, so a maintainer reading a diff --git a/crates/stella-graph/src/generated.rs b/crates/stella-graph/src/generated.rs index 61d21de33..2c25255df 100644 --- a/crates/stella-graph/src/generated.rs +++ b/crates/stella-graph/src/generated.rs @@ -6,7 +6,7 @@ //! buries genuine hits, so this module keeps them out of the store entirely. //! //! Two independent signals feed the same exclusion, both evaluated in -//! [`crate::store::index_one`] against a file's already-read bytes: +//! `index_one` (private to [`crate::store`]) against a file's already-read bytes: //! //! - **Declared**: `.gitattributes` `linguist-generated=true` patterns //! (root-level only — the same documented gap [`crate::walk`] already @@ -19,7 +19,7 @@ //! //! Directory-shaped generated output (`dist/`, `build/`, `out/`, `.next/`, //! `node_modules/`, `dist-standalone/`, `vendor/`) is excluded earlier, at -//! the walk itself ([`crate::walk::DENY_DIRS`]) — cheaper, since the walk +//! the walk itself (`DENY_DIRS` in [`crate::walk`]) — cheaper, since the walk //! never even opens those files. //! //! Both checks here run **before** the byte-compat skip diff --git a/crates/stella-observatory/src/accept.rs b/crates/stella-observatory/src/accept.rs index e47f31d6c..851f51674 100644 --- a/crates/stella-observatory/src/accept.rs +++ b/crates/stella-observatory/src/accept.rs @@ -92,7 +92,7 @@ //! `stella-serve/src/accept.rs` — and duplication is only acceptable here because //! it cannot happen quietly. The two servers must not diverge (that is the whole //! point of writing the policy down), so -//! [`tests::the_two_copies_of_this_policy_have_not_drifted`] compares the two +//! `tests::the_two_copies_of_this_policy_have_not_drifted` compares the two //! files byte-for-byte at compile time. It is compiled into *both* crates, so //! `cargo test` on either one fails the instant they differ. Change one, change //! the other. diff --git a/crates/stella-serve/src/accept.rs b/crates/stella-serve/src/accept.rs index e47f31d6c..851f51674 100644 --- a/crates/stella-serve/src/accept.rs +++ b/crates/stella-serve/src/accept.rs @@ -92,7 +92,7 @@ //! `stella-serve/src/accept.rs` — and duplication is only acceptable here because //! it cannot happen quietly. The two servers must not diverge (that is the whole //! point of writing the policy down), so -//! [`tests::the_two_copies_of_this_policy_have_not_drifted`] compares the two +//! `tests::the_two_copies_of_this_policy_have_not_drifted` compares the two //! files byte-for-byte at compile time. It is compiled into *both* crates, so //! `cargo test` on either one fails the instant they differ. Change one, change //! the other. diff --git a/crates/stella-serve/src/lifecycle.rs b/crates/stella-serve/src/lifecycle.rs index c58e89581..59da6112e 100644 --- a/crates/stella-serve/src/lifecycle.rs +++ b/crates/stella-serve/src/lifecycle.rs @@ -230,7 +230,7 @@ fn shutting_down(state: &Arc) { /// operator sends from a terminal). Whichever arrives first resolves. /// /// On a non-Unix target only `Ctrl-C` exists, so that is the whole of it. -/// Returning a future rather than installing anything eagerly keeps [`serve`] +/// Returning a future rather than installing anything eagerly keeps [`serve`](crate::server::serve) /// the only place with a process-wide side effect. pub(crate) async fn termination_signal() { #[cfg(unix)] diff --git a/crates/stella-serve/src/server.rs b/crates/stella-serve/src/server.rs index fd84fdd01..319f8b010 100644 --- a/crates/stella-serve/src/server.rs +++ b/crates/stella-serve/src/server.rs @@ -11,7 +11,7 @@ //! | `GET /readyz` | readiness — is it safe to send new work (#1131) | //! | `GET /v1/metrics` | counters ([`crate::observe::Snapshot`]) — authenticated, pull-only | //! | `POST /v1/turns` | start a turn (`TurnRequest` body) → `{ "turn_id": … }` | -//! | `GET /v1/turns/{id}/events` | SSE stream of [`ServerFrame`]s until `turn_complete` | +//! | `GET /v1/turns/{id}/events` | SSE stream of [`ServerFrame`](crate::frame::ServerFrame)s until `turn_complete` | //! | `POST /v1/turns/{id}/tool-result` | answer a `tool_request` (`ToolResultIn`) | //! | `POST /v1/turns/{id}/provider-result` | answer a `provider_request` (`ProviderResultIn`) | //! | `POST /v1/turns/{id}/cancel` | end an in-flight turn → `{ "status": "cancelled" }` | @@ -89,7 +89,7 @@ //! - Cancelling a turn nobody has streamed also works, and reclaims its thread. //! //! Cancellation and the reverse-request deadline -//! ([`SessionSpec::reverse_request_timeout`]) are the two bounds on a turn that +//! ([`SessionSpec::reverse_request_timeout`](crate::session::SessionSpec::reverse_request_timeout)) are the two bounds on a turn that //! stops making progress: the deadline is the automatic one, cancel the manual //! one. @@ -616,7 +616,7 @@ impl ServerState { /// Called when a stream ends because the *peer* went away, rather than /// because the turn finished. The session goes back into its entry so a /// reconnect can pick it up, and a task is armed to cancel the turn if - /// nobody does within [`RESUME_GRACE`]. + /// nobody does within the configured `resume_grace` (see [`DEFAULT_RESUME_GRACE`]). /// /// `generation` is the value read when this stream took the session. The /// reaper cancels only if it is still current: a later subscriber bumps it, diff --git a/crates/stella-serve/src/session.rs b/crates/stella-serve/src/session.rs index bd1a9de83..f0c8068a5 100644 --- a/crates/stella-serve/src/session.rs +++ b/crates/stella-serve/src/session.rs @@ -458,7 +458,7 @@ impl Drop for Session { /// mutated on the way there. /// /// `Engine::run_turn` writes those back through `&mut` borrows. Driving steps -/// means owning a [`TurnState`] instead, so they come back as values — which +/// means owning a `TurnState` instead, so they come back as values — which /// is also what makes the transcript available to checkpoint *between* steps /// rather than only after the turn. pub(crate) struct DrivenTurn { diff --git a/crates/stella-store/src/lib.rs b/crates/stella-store/src/lib.rs index 82be28bf5..97824b478 100644 --- a/crates/stella-store/src/lib.rs +++ b/crates/stella-store/src/lib.rs @@ -1830,7 +1830,7 @@ impl Store { /// Execute a `SELECT *`-style query and return a JSON array string, one /// object per row. Column names come from the query cursor. Used by - /// [`export_all_json`] for the uniform tables. + /// [`export_all_json`](Store::export_all_json) for the uniform tables. fn query_to_json(&self, conn: &Connection, sql: &str) -> Result { let mut stmt = conn.prepare(sql)?; let col_count = stmt.column_count(); diff --git a/crates/stella-store/src/reconstruct.rs b/crates/stella-store/src/reconstruct.rs index 38302a0cf..70659fed9 100644 --- a/crates/stella-store/src/reconstruct.rs +++ b/crates/stella-store/src/reconstruct.rs @@ -199,9 +199,9 @@ fn sha256_hex(s: &str) -> String { pub(crate) struct JournalPreimages { tool_calls: HashMap, tool_outputs: HashMap, - /// `content_digest` ("sha256:") → the assistant text bytes. + /// `content_digest` (`sha256:`) → the assistant text bytes. text_by_digest: HashMap, - /// `content_digest` ("sha256:") → the serialized post-rewrite tool + /// `content_digest` (`sha256:`) → the serialized post-rewrite tool /// output a compaction pass journaled (#1667). Consulted before the /// `call_id` fallback: a compacted block's digest resolves here exactly, /// where the `call_id` route can only reach the pre-compaction bytes. diff --git a/crates/stella-tools/src/authored_diff.rs b/crates/stella-tools/src/authored_diff.rs index a25dffa11..dc8c6a7b5 100644 --- a/crates/stella-tools/src/authored_diff.rs +++ b/crates/stella-tools/src/authored_diff.rs @@ -72,7 +72,7 @@ use crate::file_touch::{FileOp, changed_region_diff, line_diff}; /// hand-rolled variant here would silently blind it — the same defect that once /// let a turn creating a new source file classify as docs-only. The two crates /// cannot share a constant (neither depends on the other), so -/// [`tests::marker_line_matches_the_pipeline_contract`] pins the literal +/// `tests::marker_line_matches_the_pipeline_contract` pins the literal /// instead. const MARKER_PREFIX: &str = "+ untracked change: "; diff --git a/crates/stella-tools/src/bash.rs b/crates/stella-tools/src/bash.rs index dc4e5b44f..775200533 100644 --- a/crates/stella-tools/src/bash.rs +++ b/crates/stella-tools/src/bash.rs @@ -72,7 +72,7 @@ const GREP_CMDS: &[&str] = &["grep", "egrep", "fgrep", "rg", "ripgrep", "ag"]; /// pattern out of the common command shapes, returning each word already /// unquoted. NOT a shell parser: it respects `'…'` and `"…"` (so a pattern or /// path with spaces stays one word) and preserves backslash escapes like -/// `\|` (so an alternation survives into [`is_symbol_shaped`]); unquoted +/// `\|` (so an alternation survives into [`is_symbol_shaped`](crate::code_map::is_symbol_shaped)); unquoted /// operators (`&&`, `||`, `|`, `;`, `&`) come back as their own words to /// bound a scan — including when attached to a word, so `cd /app; ls` yields /// the target `/app`, not the unresolvable `/app;` a paid bench trial saw diff --git a/crates/stella-tools/src/project.rs b/crates/stella-tools/src/project.rs index 81b8d4048..66ff311f8 100644 --- a/crates/stella-tools/src/project.rs +++ b/crates/stella-tools/src/project.rs @@ -418,7 +418,7 @@ fn test_command( /// Resolve `build_project`'s or `run_tests`'s command line for the /// registry's `command.started` policy chain, mirroring -/// [`crate::scripts::resolve_command_for_gate`] — best-effort: `None` (no +/// [`crate::scripts`]'s private `gate::resolve_command_for_gate` — best-effort: `None` (no /// gating from here) when the index composes nothing, in which case the /// tool itself returns the named error. An explicit `command` override also /// resolves to `None`: the registry reads that straight off the input, so diff --git a/crates/stella-tools/src/registry.rs b/crates/stella-tools/src/registry.rs index 8253bb285..35ba94baa 100644 --- a/crates/stella-tools/src/registry.rs +++ b/crates/stella-tools/src/registry.rs @@ -1538,7 +1538,7 @@ impl ToolRegistry { /// /// Every tool that reaches `bash -c` MUST ride the same fence as `bash`: /// they stay in the surface when an operator sets `"bash": "off"` (and - /// `start_process`'s argv[0] may itself be a shell, `["bash", "-c", …]`), + /// `start_process`'s `argv[0]` may itself be a shell, `["bash", "-c", …]`), /// so leaving any out hands ambient shell execution to the very posture /// that turned `bash` off. The #615 known gap is closed (#804): the /// `bash -c` composers (`screenshot`, `ci_status`, `start_work_on_issue`) diff --git a/crates/stella-tools/src/repo.rs b/crates/stella-tools/src/repo.rs index 0edbecb3e..35e73eb4f 100644 --- a/crates/stella-tools/src/repo.rs +++ b/crates/stella-tools/src/repo.rs @@ -245,7 +245,7 @@ impl GitCli { /// stderr into stdout, so any of that chatter lands inside the value the /// caller is about to parse. A branch name is the sharp case: `rev-parse /// --abbrev-ref HEAD` plus one hint becomes a "branch" that git rejects as - /// `fatal: invalid refspec` when [`RepoBackend::push`] builds a refspec + /// `fatal: invalid refspec` when [`RepoBackend::push_branch`] builds a refspec /// from it. `verify` already moved its own reads to stdout-only for exactly /// this reason; these call sites had not. /// diff --git a/crates/stella-tools/src/web.rs b/crates/stella-tools/src/web.rs index 3495486e2..38f52e71d 100644 --- a/crates/stella-tools/src/web.rs +++ b/crates/stella-tools/src/web.rs @@ -268,7 +268,7 @@ fn search_client() -> Result { /// `Arc`-internal, so handing out clones is free. /// /// The per-domain user agent was the only thing that varied between them, and -/// it does not need to be baked into the client: [`fetch_url`] sends it as a +/// it does not need to be baked into the client: [`fetch_raw`] sends it as a /// per-request header, which overrides this default and, like the default, /// carries across redirects. fn client_for(policy: &Arc) -> Result { diff --git a/crates/stella-tui/src/deck_ui.rs b/crates/stella-tui/src/deck_ui.rs index 208dc3d50..10c7fc102 100644 --- a/crates/stella-tui/src/deck_ui.rs +++ b/crates/stella-tui/src/deck_ui.rs @@ -3984,7 +3984,7 @@ fn handle_composer_key(key: KeyEvent, ui: &mut DeckUi, model: &WorkspaceModel) - } } -/// Cycle the trace filter: None → agent[0] → agent[1] → … → None. +/// Cycle the trace filter: None → `agent[0]` → `agent[1]` → … → None. fn cycle_filter(model: &WorkspaceModel, current: Option<&str>) -> Option { if model.agents.is_empty() { return None; diff --git a/crates/stella-tui/src/deck_ui/create.rs b/crates/stella-tui/src/deck_ui/create.rs index 546c74ed1..affaeb66f 100644 --- a/crates/stella-tui/src/deck_ui/create.rs +++ b/crates/stella-tui/src/deck_ui/create.rs @@ -18,9 +18,10 @@ //! Two consequences worth stating, since both are load-bearing: //! //! - **The completion signal is a driver snapshot, not the keypress.** The -//! in-flight states ([`super::InstalledMode::Creating`], +//! in-flight states ([`InstalledMode::Creating`](crate::deck_ui::InstalledMode::Creating), //! [`super::SkillPrompt::Creating`]) are left by -//! [`settle_agents_snapshot`] / [`settle_skills_snapshot`], never by a key. +//! [`settle_agents_snapshot`](crate::deck_ui::create::settle_agents_snapshot) / +//! [`settle_skills_snapshot`](crate::deck_ui::create::settle_skills_snapshot), never by a key. //! An interim snapshot for a *parked* create carries `creating: true` //! precisely so it cannot be mistaken for the real thing. //! - **Esc hides, it does not cancel.** The driver-side draft keeps running diff --git a/crates/stella-tui/src/render.rs b/crates/stella-tui/src/render.rs index 1cb2ed6fa..64dd1b12c 100644 --- a/crates/stella-tui/src/render.rs +++ b/crates/stella-tui/src/render.rs @@ -184,7 +184,7 @@ fn park_subject(description: &str) -> String { } } -/// [`render_transcript`] for a caller that already materialized just the +/// The transcript panel for a caller that already materialized just the /// visible window (the deck's fold cache clones ≤ one viewport of lines per /// frame instead of the whole history); `total` sizes the title. `hint`, when /// set, renders as a dim bottom title — the contextual "what can I press @@ -438,7 +438,7 @@ pub(crate) fn slash_popup_area(root: Rect, composer: Rect, matches: usize) -> Re /// The first visible row of a scrolling list of `len` rows that shows /// `visible` at a time, chosen so `selected` stays on screen — the window /// only moves once the selection would fall off an edge. Mirrors the -/// composer's cursor-row windowing ([`render_composer`]) so the slash popup +/// composer's cursor-row windowing (`render_composer` in [`crate::deck_render`]) so the slash popup /// and the textarea scroll with identical feel. pub(crate) fn scroll_window_start(len: usize, selected: usize, visible: usize) -> usize { if visible == 0 || len <= visible { diff --git a/crates/stella-tui/src/render/row.rs b/crates/stella-tui/src/render/row.rs index 1cf29db89..83b4e0c4c 100644 --- a/crates/stella-tui/src/render/row.rs +++ b/crates/stella-tui/src/render/row.rs @@ -187,7 +187,7 @@ pub(crate) fn wrap_one_indent( /// [`push_row_block`] for multi-line content) — no transcript row renders at /// the left margin without a rail. The /// `every_transcript_entry_renders_on_a_rail` test enforces it, with exactly -/// one deliberate exception: [`TranscriptEntry::Evicted`] is a system note +/// one deliberate exception: [`TranscriptEntry::Evicted`](crate::model::TranscriptEntry::Evicted) is a system note /// *about* the transcript rather than an entry in it, so it renders untagged /// and full-bleed. pub(crate) fn push_row(