Browse the workspace's crate READMEs from the terminal: index them with a one-line summary each, open one by crate name (no path, no .md), or search across all of them -- paged through $PAGER. The estate has one README per crate across seven tiers, which is more than anyone greps by hand and more than fits on a screen; `gen-ai-context` regenerates the crate index for AI_CONTEXT.md but nothing reads them back.
| Tier | tools |
| Role | tooling |
| Path | crates/tools/doc-read |
| Edition | 2021 |
| Targets | doc-read, tools_doc_read |
| Public items | 32 across 1 module |
| Tests | 29 |
What it is for
Index and address the workspace's crate READMEs.
Two sources, one question set: this module answers from the README files a person reads, and rows answers the same standing questions from corpus_sourcecode. A caller picks a source; it does not restate a question, because a restated question answers differently within a week.
Pure logic only — resolving a crate reference, summarising a README, ranking search hits — so it is testable without a filesystem. The walking, reading and paging live in main.rs.
The addressing rule is the point: a crate is named identity-auth in its manifest and lives at crates/identity/auth, so an operator reasonably types any of identity-auth, identity/auth or just auth. All three resolve, and a bare name that matches several crates reports the candidates instead of picking one.
Capabilities
crate root
Index and address the workspace's crate READMEs.
| Item |
|---|
fn resolve <'a>(docs : & 'a CrateDoc, query : & str) -> Resolution <'a> |
fn summarize(readme : & str, width : usize) -> String |
fn first_sentence(text : & str, width : usize) -> String |
fn bug_digest(markdown : & str) ->(String, String) |
fn crate_of_path(path : & str) -> Option <(String, String)> |
fn pending_migrations(files : & u64, applied : & u64) -> Vec <u64> |
fn applied_beyond_files(files : & u64, applied : & u64) -> Vec <u64> |
pub const TIER_ORDER: & & str |
fn tier_rank(tier : & str) -> usize |
fn tier_glosses(manifest : & str) -> std::collections::BTreeMap <String, String> |
CrateDoc
Index and address the workspace's crate READMEs.
| Item |
|---|
pub struct CrateDoc |
CrateDoc :: fn slug(& self) -> String |
Hit
Index and address the workspace's crate READMEs.
| Item |
|---|
pub struct Hit |
fn search_readme(crate_name : & str, body : & str, term : & str) -> Vec <Hit> |
LexiconRow
Index and address the workspace's crate READMEs.
| Item |
|---|
pub struct LexiconRow |
fn parse_lexicon(tsv : & str) -> Vec <LexiconRow> |
Resolution
Index and address the workspace's crate READMEs.
| Item |
|---|
pub enum Resolution<'a> |
rows (other)
The same standing questions, answered from rows rather than from files.
| Item |
|---|
pub const MAX_ROWS: i64 |
pub const STATEMENT_TIMEOUT_MS: i32 |
pub const MAX_SUBJECT_BYTES: usize |
fn ask(question : & str, subject : & str) -> Result <(Question, String), AskRefusal> |
AskRefusal
The same standing questions, answered from rows rather than from files.
| Item |
|---|
pub enum AskRefusal |
AskRefusal :: fn fmt(& self, f : & mut fmt::Formatter <'_>) -> fmt::Result |
Question
The same standing questions, answered from rows rather than from files.
| Item |
|---|
pub enum Question |
Question :: fn as_str(self) -> & 'static str |
Question :: fn source(self) -> Source |
Question :: fn all() -> Question; 7 |
Question :: fn description(self) -> & 'static str |
Question :: fn sql(self) -> & 'static str |
Question :: fn fmt(& self, f : & mut fmt::Formatter <'_>) -> fmt::Result |
Source
The same standing questions, answered from rows rather than from files.
| Item |
|---|
pub enum Source |
Source :: fn fmt(& self, f : & mut fmt::Formatter <'_>) -> fmt::Result |
How to use it
No examples/ target and no doctest in this crate's rustdoc. The tests listed under Verification are the closest executable usage.
Module structure
tools_doc_read
rows
Public surface
`crate root`
| Item | What it is |
|---|---|
pub struct CrateDoc | One crate's README, as the index sees it. |
CrateDoc :: fn slug(& self) -> String | identity/auth — how the index prints a crate's location. |
pub enum Resolution<'a> | What a crate reference resolved to. |
fn resolve <'a>(docs : & 'a CrateDoc, query : & str) -> Resolution <'a> | Resolve identity-auth, identity/auth, auth, or a unique prefix |
fn summarize(readme : & str, width : usize) -> String | The first line of real prose in a README, for the one-line index |
fn first_sentence(text : & str, width : usize) -> String | The first sentence of a description, for a one-line index entry |
pub struct LexiconRow | One enforced vocabulary rule, as the lexicon records it. |
fn parse_lexicon(tsv : & str) -> Vec <LexiconRow> | Parse docs/reference/lexicon-policy.tsv |
fn bug_digest(markdown : & str) ->(String, String) | Title and severity/status of a bug file, for a one-line listing |
fn crate_of_path(path : & str) -> Option <(String, String)> | crates/identity/auth/src/api_key.rs -> ("identity", "auth") |
fn pending_migrations(files : & u64, applied : & u64) -> Vec <u64> | Migration versions present as files but not recorded as applied |
fn applied_beyond_files(files : & u64, applied : & u64) -> Vec <u64> | Versions recorded as applied with no matching file — a database ahead of the code, which is how a checkout ends up unable to build against its own DB. |
pub struct Hit | One matching line from a search. |
fn search_readme(crate_name : & str, body : & str, term : & str) -> Vec <Hit> | Case-insensitive line matches in one README. |
pub const TIER_ORDER: & & str | Tier order for listings: the dependency direction of the estate, so a reader goes bottom-up rather than alphabetically through unrelated layers. |
fn tier_rank(tier : & str) -> usize | Sort key for a tier: its position in TIER_ORDER, unknown tiers last. |
fn tier_glosses(manifest : & str) -> std::collections::BTreeMap <String, String> | What each tier MEANS, read from the section comments in the workspace manifest |
`rows`
| Item | What it is |
|---|---|
pub const MAX_ROWS: i64 | How many rows any question may return, whatever it was asked. |
pub const STATEMENT_TIMEOUT_MS: i32 | How long a single read may run before the database is told to stop. |
pub const MAX_SUBJECT_BYTES: usize | The longest subject a question accepts, so a pasted file cannot become a query parameter. |
pub enum Source | Which database answers a question |
Source :: fn fmt(& self, f : & mut fmt::Formatter <'_>) -> fmt::Result | — |
pub enum Question | One of the workspace's standing questions. |
Question :: fn as_str(self) -> & 'static str | The name a caller uses. |
Question :: fn source(self) -> Source | Which record answers it. |
Question :: fn all() -> Question; 7 | Every question, in the order they are advertised. |
Question :: fn description(self) -> & 'static str | One line saying what the question answers, for a caller that has to describe the catalog to someone else. |
Question :: fn sql(self) -> & 'static str | The parameterised read |
Question :: fn fmt(& self, f : & mut fmt::Formatter <'_>) -> fmt::Result | — |
pub enum AskRefusal | Why a question could not be asked. |
AskRefusal :: fn fmt(& self, f : & mut fmt::Formatter <'_>) -> fmt::Result | — |
fn ask(question : & str, subject : & str) -> Result <(Question, String), AskRefusal> | Resolve a caller's arguments into a question and its subject |
No pub use re-exports: every item above is declared in this crate.
Boundary
Depends on no other workspace tier.
Shares tier tools with 84 other crates: tools-advisory-reach, tools-archive-guard, tools-artifact-scaffold, tools-ask-ai-core, tools-ask-ais, tools-ask-gemini, tools-book, tools-book-report, … (84 total).
_What this crate deliberately does NOT own is a judgment. No committed registry records one for it, so none is stated here._
Where it sits
| Tier (ontology) | tools |
| Architectural role (taxonomy) | tooling |
| Location | crates/tools/doc-read |
| Vocabulary in force (lexicon) | current |
Dependencies
Runtime, from outside the workspace.
| Crate | Requirement | Features | Optional | Only on |
|---|---|---|---|---|
anyhow | ^1 | — | no | always |
Development. None.
Build. None.
Depended on by. 1 workspace crate.
Signal flow — what reaches this crate, and what it reaches.
flowchart LR n_tools_imp["tools-imp"] -->|uses| SELF SELF["tools-doc-read"] classDef self fill:#1f883d,stroke:#1f883d,color:#fff; class SELF self;
Feature flags
No Cargo features are defined: every capability is unconditional, so no consumer can receive a half-wired crate.
Targets
| Kind | Name | Source |
|---|---|---|
| bin | doc-read | `src/main.rs` |
| lib | tools_doc_read | `src/lib.rs` |
Error model
No public error type was detected: no public item declares a type named *Error, and no public signature returns one.
Operational characteristics
| Property | Evidence |
|---|---|
| async public surface | none detected |
| async runtime | none detected |
| database access | none detected |
| network I/O | none detected |
| unsafe code | none detected |
| environment variables | yes |
No unsafe block, unsafe fn, unsafe impl or unsafe trait was found by the parser anywhere in this crate's source.
Configuration
| Variable | Read in |
|---|---|
PAGER | src/main.rs |
Related capabilities
1 workspace crate depends on this one: tools-imp.
Verification
| Kind | Count |
|---|---|
| Unit tests | 29 |
| Integration tests | 0 |
| Examples | 0 |
| Doctests | 0 |
Evidence by module. How often each public module is named by something executable.
| Module | Tests | Examples | Consumers |
|---|---|---|---|
crate root | 16 | 0 | 2 |
rows | 7 | 0 | 5 |
What the tests establish, by name:
a_bare_stem_resolves_when_it_is_unique—src/lib.rsa_bug_file_reduces_to_its_title_and_severity—src/lib.rsa_bug_file_using_status_instead_of_severity_still_digests—src/lib.rsa_changed_path_attributes_to_its_crate—src/lib.rsa_database_ahead_of_the_code_is_reported_separately—src/lib.rsa_long_first_sentence_is_still_truncated_to_width—src/lib.rsa_package_name_resolves_exactly—src/lib.rsa_paragraph_description_reduces_to_its_first_sentence—src/lib.rsa_readme_with_no_prose_summarizes_to_empty_rather_than_a_heading—src/lib.rsa_summary_skips_fenced_code—src/lib.rsa_summary_skips_the_title_badges_and_callouts—src/lib.rsa_summary_strips_inline_markup_and_keeps_link_text—src/lib.rsan_abbreviation_does_not_end_the_sentence—src/lib.rsan_ambiguous_stem_reports_every_candidate—src/lib.rsan_empty_search_term_matches_nothing_rather_than_everything—src/lib.rsan_underscored_source_ident_resolves_like_the_package_name—src/lib.rsnothing_matching_resolves_to_none—src/lib.rspending_migrations_are_the_files_the_database_has_not_recorded—src/lib.rssearch_reports_line_numbers_case_insensitively—src/lib.rsthe_first_gloss_for_a_tier_wins_so_later_notes_do_not_overwrite_it—src/lib.rsthe_lexicon_parses_into_term_preference_and_reason—src/lib.rsthe_tier_slash_stem_form_resolves—src/lib.rstier_glosses_come_from_the_manifest_section_comments—src/lib.rstiers_sort_in_dependency_order_with_unknowns_last—src/lib.rsa_question_names_the_record_that_answers_it—src/rows.rsa_subject_is_a_name_not_a_pasted_file—src/rows.rsevery_question_is_a_bounded_read_and_none_of_them_writes—src/rows.rsthe_caps_are_the_ones_the_security_gate_asks_for—src/rows.rsthe_five_questions_resolve_and_an_invented_one_is_refused—src/rows.rs
Documentation coverage
| Measure | Documented | Total |
|---|---|---|
| Public items with rustdoc | 29 | 32 |
Public modules with a //! block | 1 | 1 |
pie showData
title Public items with rustdoc
"Documented" : 29
"No rustdoc detected" : 3
Metrics
| Metric | Value |
|---|---|
| Rust source files | 3 |
| Source lines | 2412 |
| Code lines | 2013 |
| Public API items | 32 |
| Public modules | 1 |
| Tests | 29 |
| Examples | 0 |
| Cargo features | 0 |
| Direct runtime dependencies | 1 |
| Workspace reverse dependencies | 1 |
pie showData
title Public API by kind
"constant" : 4
"enum" : 4
"function" : 12
"method" : 9
"struct" : 3
pie showData
title Rust source composition
"Code" : 2013
"Blank or comment" : 399
Generation
Rendered by tools-corpus corpus readme from repository evidence alone, renderer schema 2, lexicon current. No model, network service or database was consulted. Regenerate with tools-corpus corpus readme --write; verify with --check.