Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -226,8 +226,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)
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-context/src/ann.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions crates/stella-context/src/candidates.rs
Original file line number Diff line number Diff line change
Expand Up @@ -309,12 +309,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.
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-context/src/retrieval.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};

Expand Down
6 changes: 3 additions & 3 deletions crates/stella-context/src/retrieval/ranking.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<i64>, f64)], k: f64) -> HashMap<i64, f64> {
let mut scores: HashMap<i64, f64> = HashMap::new();
for (list, weight) in lists {
Expand Down Expand Up @@ -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.
Expand Down Expand Up @@ -225,7 +225,7 @@ pub(crate) fn mmr_select(items: &[MmrItem<'_>], lambda: f32) -> Vec<usize> {
/// 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`
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-context/src/store/domain.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-context/src/store/schema.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions crates/stella-core/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down Expand Up @@ -2551,7 +2551,7 @@ type SpeculationFuture<'a> = Pin<Box<dyn Future<Output = SpeculationPool> + '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";
Expand Down
4 changes: 2 additions & 2 deletions crates/stella-core/src/driver/loop_evidence.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
4 changes: 2 additions & 2 deletions crates/stella-core/src/receipts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-core/src/step.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-diag/src/dx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-diag/src/redact.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
4 changes: 2 additions & 2 deletions crates/stella-graph/src/generated.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-observatory/src/accept.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-serve/src/accept.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-serve/src/lifecycle.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ fn shutting_down(state: &Arc<ServerState>) {
/// 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)]
Expand Down
6 changes: 3 additions & 3 deletions crates/stella-serve/src/server.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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" }` |
Expand Down Expand Up @@ -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.

Expand Down Expand Up @@ -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,
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-serve/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-store/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<String> {
let mut stmt = conn.prepare(sql)?;
let col_count = stmt.column_count();
Expand Down
4 changes: 2 additions & 2 deletions crates/stella-store/src/reconstruct.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,9 +199,9 @@ fn sha256_hex(s: &str) -> String {
pub(crate) struct JournalPreimages {
tool_calls: HashMap<String, ToolCall>,
tool_outputs: HashMap<String, ToolOutput>,
/// `content_digest` ("sha256:<hex>") → the assistant text bytes.
/// `content_digest` (`sha256:<hex>`) → the assistant text bytes.
text_by_digest: HashMap<String, String>,
/// `content_digest` ("sha256:<hex>") → the serialized post-rewrite tool
/// `content_digest` (`sha256:<hex>`) → 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.
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-tools/src/authored_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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: ";

Expand Down
2 changes: 1 addition & 1 deletion crates/stella-tools/src/bash.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-tools/src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-tools/src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1531,7 +1531,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`)
Expand Down
2 changes: 1 addition & 1 deletion crates/stella-tools/src/repo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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.
///
Expand Down
Loading
Loading