fix(gate): unbreak main — a public item may not intra-doc-link a private one - #2365
Conversation
…ate one `WorkspaceProbe::diff` (pub) linked [`Self::ignores`] (private), which `rustdoc::private_intra_doc_links` rejects under `-D warnings`. Every PR opened against main is red until this lands. Landed by #2344 and not caught locally: the branch predated #2354, so the `cargo doc` gate it ran was the older command. Worth noting for #2336/#2354: `--document-private-items` does NOT silence this lint for a pub → private link. rustdoc's own hint says it will, and that hint is what made the link look safe. The gate is doing its job; the rule is simply that public docs cite private helpers in prose, not as links. Refs #2344
|
The latest updates on your projects. Learn more about Vercel for GitHub. 1 Skipped Deployment
|
There was a problem hiding this comment.
Sorry @macanderson, you have reached your weekly rate limit of 500000 diff characters.
Please try again later or upgrade to continue using Sourcery
Reviewer's guide (collapsed on small PRs)Reviewer's GuideFixes a failing rustdoc gate by removing an intra-doc link from a public method’s documentation to a private helper, converting the reference to plain prose instead. File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
|
Independently verified this is the complete unbreak, not just the one CI showed: I ran the full strengthened gate command ( One note for the record: |
`cargo doc -D warnings` fails this branch:
error: public documentation for `workspace_ignore` links to private
item `crate::walk`
--> crates/stella-graph/src/workspace_ignore.rs:4
error: could not document `stella-graph`
`workspace_ignore` is `pub mod`; `walk` is a private `mod`.
`rustdoc::private_intra_doc_links` denies that under `-D warnings`, and
`--document-private-items` does not silence it for a public → private
link — the same rule and the same fix shape as #2365.
The link becomes prose. No API change, no behavior change.
…gnore rules (#2360) (#2366) ## What & why Closes #2360. `crates/stella-graph/src/walk.rs` has carried this in its own module doc for two releases: > **Documented gap (task brief, ignore-discipline clause):** custom `.gitignore` patterns (per-directory ignore files, negations, glob rules) are *not* honored — only the built-in deny-list is. So a generated directory whose name the deny-list has never heard of — `generated-sdk/`, a sibling checkout, anything project-specific — was indexed into the code graph and paid for on every recall. #2344 closed the same gap for the *workspace probe*; this closes it for the *index*, and makes the two share one answer instead of two approximations. ## The design: ask git, don't reimplement it New `stella-graph::workspace_ignore` resolves the rules once per walk with `git ls-files -z --others --ignored --directory --exclude-standard`. Per-directory ignore files, negations, globs, `.git/info/exclude`, and the user's global excludesfile therefore behave exactly as they do at the command line — because the answer **is** git's. A hand-rolled matcher would be a second ignore engine to keep correct forever, and its failure mode is silent: a file quietly indexed, or quietly not. **Where it lives, and why that is not arbitrary.** `stella-tools` already depends on `stella-graph` and not the reverse, so putting the resolver here lets one implementation serve both walkers with **no new crate and no new dependency edge** — and it costs `stella-graph` nothing but `std`. The alternative considered and rejected was pulling ripgrep's `ignore` crate: it would give this crate a dependency *and* leave `stella-tools` on a different mechanism, so the two could disagree about the same tree. `stella-tools`' private copy from #2344 is deleted in this PR. **The deny-list survives beside the rules, not under them.** They answer different questions: the rules say what *this repository does not track*, the deny-list says what is *never worth parsing*. A Terminal-Bench task directory is not a repository, so it has no rules to consult — and there the deny-list is the only thing keeping a vendored bundle out of the index. Witnessed both ways. **The watcher resolves once at construction**, not per event. The relevance filter runs on every saved file; resolving per call would be one `git` invocation per write. The window that opens is a `.gitignore` edited while a session is live, whose new rules are not seen until the next full index pass — one wasted re-index, never a wrong row, and the same direction every other bound in this subsystem fails. ## A defect #2344 shipped, fixed here `HostDataIsolation::ProcessFree` promises that the registry "omit[s] every built-in tool that launches a child process". #2344's probe spawned `git` unconditionally to resolve ignore rules — including under that attestation. It now resolves to `IgnorePolicy::WalkAll` whenever the registry is process-free, whatever the `ignore_gitignore` setting says. Losing the filter there costs walk time, which `MAX_RECORDED_TOUCHES` already bounds; honoring the setting instead would cost the guarantee. This is the "a field's second consumer arms what the first never checked" shape: `process_free` was consulted at construction for tools and for exploration coverage, and the probe's new subprocess simply never asked. ## The witness - [x] This PR includes witness tests (fail on `main`, pass here) | Test | File | Proves | |---|---|---| | `a_repositorys_own_ignore_rules_are_honored_including_globs_and_negations` | `stella-graph/src/walk.rs` | the closed gap — an ignored dir, a glob, **and** a negation re-admitting one file | | `the_deny_list_still_applies_when_there_are_no_rules_to_consult` | `stella-graph/src/walk.rs` | the non-repository posture is unchanged | | `a_watcher_event_for_an_ignored_path_is_not_relevant` | `stella-graph/src/walk.rs` | live re-index honors the same answer | | `a_repositorys_own_rules_are_resolved_including_a_collapsed_directory` | `stella-graph/src/workspace_ignore.rs` | `--directory` collapsing, and `excludes` vs `excludes_dir` | | `a_non_repository_ignores_nothing_even_inside_a_repository` | `stella-graph/src/workspace_ignore.rs` | the repo-root gate: a `$HOME` dotfiles repo ignoring `*` cannot blind a scratch dir under it | | `a_process_free_registry_never_consults_the_repositorys_ignore_rules` | `stella-tools/src/registry/tests/file_change.rs` | the isolation fix, **with a control** asserting the same option is honored outside isolation | The pre-existing `dist_standalone_and_next_directories_are_never_walked` is unchanged and still green — that is the non-repository posture stated as a test that predates this PR. ## God-file accounting `registry.rs` sat at its exact ratchet ceiling again, so the process-free resolution went to `RegistryOptions::effective_probe_ignore_policy` in `registry/options.rs` and the accessor to `registry/turn_probe.rs`. `registry.rs` nets **−7**; `shell_touch.rs` nets **−42** from deleting the duplicated resolver. `file-size` is green and reports "none grew by this change". ## Docs `crates/stella-graph/README.md`'s "Gotchas" entry claimed the gap; it now describes the two-filter arrangement. The `.gitattributes` half of that entry is genuinely still unresolved and is now stated separately rather than bundled with a gap that is closed. ## The gate Not run locally — a Terminal-Bench match is executing on this machine (`harbor run … sqlite-with-gcov`) and a workspace build would contend for CPU, which is how a trial acquires a false timeout. `make guards-fast` is green, including `file-size`, `god-files`, `module-reachability` and `fmt --check`. The compile tiers are deliberately CI's. **Opened as a draft on purpose**: it is unverified until CI compiles it, and this repository merges PRs fast. Marking it ready is the signal that the build is green. - [ ] `cargo fmt --check` · [ ] `cargo clippy --workspace --all-targets -- -D warnings` · [ ] `cargo test --workspace` - [x] Docs updated where behavior changed ## Depends on **#2365** unbreaks `main` (a public item intra-doc-linking a private one, landed by #2344). Until that merges, this PR is red for a reason that has nothing to do with it. This branch already carries the equivalent fix, so expect a one-line conflict on rebase. ## Ground-rule check - [x] No I/O added to `stella-core`; **no new dependencies in any crate** - [x] No new outbound network calls - [x] No new cross-boundary types (`WorkspaceIgnore` is internal to the tool/graph layer, not a protocol type) ## Nothing left behind - `.gitattributes` per-directory merging remains unresolved and is now named on its own in the README gotcha rather than hidden inside a gap that is closed. It is pre-existing, unrelated to the walk, and already visible to a reader of that section. ## Summary by Sourcery Unify and harden workspace ignore handling by introducing a shared git-backed WorkspaceIgnore resolver used by both the code-graph walk and workspace probes, ensuring repository .gitignore rules are honored alongside the existing deny-list while preserving process-free isolation guarantees. New Features: - Honor repository-specific .gitignore rules when walking and indexing the code graph, including per-directory files, globs, negations, and standard git exclude sources. - Expose a shared WorkspaceIgnore resolver in stella-graph for reuse by both the code-graph walk and stella-tools' workspace probe. Bug Fixes: - Ensure process-free tool registries never spawn git by forcing an unfiltered walk policy regardless of the configured ignore setting, restoring HostDataIsolation::ProcessFree guarantees. Enhancements: - Combine repository ignore rules with the existing deny-list so non-repository workspaces still avoid indexing vendored or build output while repositories respect their own tracked/untracked state. - Apply repository ignore rules to filesystem watcher events so live re-indexing uses the same exclusion semantics as full walks. - Refactor workspace probe ignore handling to use WorkspaceIgnore instead of an ad hoc path set, simplifying diff logic and making ignore behavior consistent across tools. Documentation: - Update stella-graph README gotchas to describe the new dual-filter behavior for ignores and to clarify that .gitattributes handling remains root-level only. Tests: - Add integration tests validating that repository ignore rules, globs, and negations are honored by the index and watcher, that the deny-list still applies in non-repository workspaces, that WorkspaceIgnore resolution behavior is correct, and that process-free registries use an unfiltered ignore policy. --------- Co-authored-by: Claude Opus 5 <noreply@anthropic.com>
What & why
mainis red, and every open PR is red with it. One line fixes it.WorkspaceProbe::diffis public and its doc comment linked[Self::ignores], which is private.rustdoc::private_intra_doc_linksis denied under-D warnings, socargo docfails the requiredfmt + clippy + testjob:Reproduced on main's own runs at
ad92643band298b2705, not just on a PR head.How it got in
#2344 introduced the link. Its branch predated #2354, so the
cargo docgate that ran against it was the older command, and the failure it did report was read as the pre-existing shellcheck breakage that #2363 was already fixing.One thing worth a follow-up thought on #2336 / #2354
--document-private-itemsdoes not silence this lint for a public → private link. rustdoc's own note says "this link will resolve properly if you pass--document-private-items" — and bothmake doc-warningsandci.ymlalready pass it, at the exact commits that failed. So the hint is misleading for this direction.That does not weaken #2354; the gate caught a real defect. It just means the working rule is narrower than the hint suggests: a public item cites a private helper in prose, never as an intra-doc link.
pub(crate) → pub(crate)links, which #2354 was about, are unaffected.The fix
The link becomes prose. No API change, no behavior change — deliberately the smallest possible diff, because an unbreak PR that also does something else is how a red
mainstays red longer.Witness
None, and none is possible: the failing check is the witness.
cargo doc -D warningsfails onmainat this commit's parent and passes here — a witness test cannot assert about a rustdoc lint, and the gate already does.Gate
Not run locally — a Terminal-Bench match is executing on this machine and a workspace build would contend for CPU, which is how a trial acquires a false timeout.
make guards-fastis green; the compile tiers are CI's.Ground-rule check
stella-core; no new depsSummary by Sourcery
Bug Fixes: