From 92c53c94bb7849acbb9bf233f9dd3c3a081b482e Mon Sep 17 00:00:00 2001 From: "russell@unturf.com" Date: Mon, 4 May 2026 07:52:17 -0400 Subject: [PATCH] docs: add docstrings to key modules (CLI, merkle, ingest, store) Docstring coverage improvements: - aborist/cli.py: 44/55 functions (80%, was 58%) Major command handlers (_cmd_ingest, _cmd_search, _cmd_ask, etc.) documented with their purpose. - aborist/merkle.py: 3/3 classes (100%), 9/10 functions (90%, was 40%) Added docstrings to MerkleProof, build(), proof(), root, leaves. - aborist/ingest.py: 6/7 functions (86%, unchanged) - aborist/store.py: 17/18 functions (94%, unchanged) These docstrings enable code-driven documentation generation (via pdoc, Sphinx, etc.), allowing the deletion of modules.md without losing API reference coverage. Code + docstrings now serve as the authoritative module reference. --- aborist/cli.py | 12 ++++++++++++ aborist/merkle.py | 10 ++++++++++ 2 files changed, 22 insertions(+) diff --git a/aborist/cli.py b/aborist/cli.py index fc56d80..c19cfbf 100644 --- a/aborist/cli.py +++ b/aborist/cli.py @@ -24,6 +24,7 @@ from aborist.store import ( def _cmd_ingest(args: argparse.Namespace) -> int: + """Ingest a corpus (Wikipedia, HTML, git, etc.) into a shard.""" if args.source in ("wikipedia_cur", "wikipedia_old"): if not args.path: print(f"--path is required for {args.source}", file=sys.stderr) @@ -171,6 +172,7 @@ def _cmd_ingest(args: argparse.Namespace) -> int: def _cmd_search(args: argparse.Namespace) -> int: + """Search the corpus with FTS5.""" conn = ( connect_query(args.db, shards_dir=args.global_shards_dir) if args.global_shards_dir @@ -209,6 +211,7 @@ def _cmd_search(args: argparse.Namespace) -> int: def _cmd_verify(args: argparse.Namespace) -> int: + """Verify Q&A cache records and audit chains.""" conn = ( connect_query(args.db, shards_dir=args.global_shards_dir) if args.global_shards_dir @@ -223,6 +226,7 @@ def _cmd_verify(args: argparse.Namespace) -> int: def _cmd_distill(args: argparse.Namespace) -> int: + """Distill surface documents into compressed cores.""" from aborist.distill import get_distiller from aborist.distill.runner import distill_existing from aborist.store import discover_shards @@ -288,6 +292,7 @@ def _cmd_distill(args: argparse.Namespace) -> int: def _cmd_ask(args: argparse.Namespace) -> int: + """Ask a question against one document and get a grounded answer.""" import os from aborist.qa import ask @@ -1141,6 +1146,7 @@ def _render_inspect_human(result: dict) -> str: def _short(s: str, n: int) -> str: + """Truncate string to n chars with ellipsis.""" return s if len(s) <= n else s[: n - 3] + "..." @@ -2192,6 +2198,7 @@ def _cmd_emergent(args: argparse.Namespace) -> int: def _cmd_evict(args: argparse.Namespace) -> int: + """Move hot chunks to cold tier (archive unused content).""" from aborist.evict import evict_to_cold conn = ( @@ -2213,6 +2220,7 @@ def _cmd_evict(args: argparse.Namespace) -> int: def _cmd_rehydrate(args: argparse.Namespace) -> int: + """Rehydrate cold chunks from source (inverse of evict).""" from aborist.evict import rehydrate conn = ( @@ -2419,6 +2427,7 @@ def _cmd_activity(args: argparse.Namespace) -> int: def _cmd_stats(args: argparse.Namespace) -> int: + """Show corpus statistics (document count, chunk count, index size).""" conn = ( connect_query(args.db, shards_dir=args.global_shards_dir) if args.global_shards_dir @@ -2667,6 +2676,7 @@ def _cmd_snapshot_create(args: argparse.Namespace) -> int: def _cmd_snapshot_list(args: argparse.Namespace) -> int: + """List named corpus snapshots (named roots).""" from aborist.snapshot import list_snapshots conn = connect(args.db) @@ -2679,6 +2689,7 @@ def _cmd_snapshot_list(args: argparse.Namespace) -> int: def _cmd_snapshot_verify(args: argparse.Namespace) -> int: + """Verify snapshot integrity (round-trip Merkle proofs).""" from aborist.snapshot import verify_snapshot conn = ( @@ -2711,6 +2722,7 @@ def _cmd_snapshot_diff(args: argparse.Namespace) -> int: def _cmd_mesh_status(args: argparse.Namespace) -> int: + """Show mesh status (members, epochs, identity).""" from aborist.mesh import current_epoch, is_enabled, load_identity from aborist.mesh.state import roster_at diff --git a/aborist/merkle.py b/aborist/merkle.py index 0243f03..cef6be5 100644 --- a/aborist/merkle.py +++ b/aborist/merkle.py @@ -54,6 +54,11 @@ class ProofNode: @dataclass(frozen=True) class MerkleProof: + """Merkle inclusion proof: leaf + index + sibling path to root. + + Proves that a leaf at leaf_index exists in a tree with the given root. + verify_proof() recomputes the root by combining the leaf with siblings. + """ leaf: bytes leaf_index: int siblings: tuple[ProofNode, ...] @@ -68,16 +73,19 @@ class MerkleTree: @property def root(self) -> bytes: + """Root hash of the tree (topmost layer). Empty tree → ZERO_HASH.""" if not self.layers or not self.layers[-1]: return ZERO_HASH return self.layers[-1][0] @property def leaves(self) -> list[bytes]: + """Leaf hashes in input order (bottom layer of tree).""" return self.layers[0] if self.layers else [] @classmethod def build(cls, leaves: Iterable[bytes]) -> MerkleTree: + """Build tree from leaf hashes. Applies odd-element self-duplication.""" leaves = list(leaves) if not leaves: return cls(layers=[[]]) @@ -96,6 +104,7 @@ class MerkleTree: return cls(layers=layers) def proof(self, leaf_index: int) -> MerkleProof: + """Generate inclusion proof for the leaf at leaf_index.""" if not self.layers or not self.layers[0]: raise IndexError("empty tree has no proofs") if leaf_index < 0 or leaf_index >= len(self.layers[0]): @@ -149,6 +158,7 @@ def proof_to_dict(proof: MerkleProof) -> dict: def proof_from_dict(d: dict) -> MerkleProof: + """Deserialize a proof from JSON dict (inverse of proof_to_dict).""" return MerkleProof( leaf=bytes.fromhex(d["leaf"]), leaf_index=int(d["leaf_index"]),