You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
docs(CLAUDE.md): clarify project positioning and architecture overview
Refactor the documentation to better explain Vectorless as having
two distinct layers: the Rust standard (IR + navigation primitives)
and the Python reference implementation. Update project structure
description with clearer crate categorization and dependency layers.
Revise development workflow guidelines to emphasize the contract
between the standard and reference implementation.
Copy file name to clipboardExpand all lines: CLAUDE.md
+75-69Lines changed: 75 additions & 69 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -1,53 +1,55 @@
1
1
# CLAUDE.md
2
2
3
-
Vectorless is a Document Understanding Engine for AI. Compile pipeline is written in Rust; the reasoning/retrieval (ask) layer is written in Python on top of LLM tool-use. See `README.md` for the project's public positioning.
3
+
Vectorless is a Document Understanding Engine for AI. See `README.md` for the project's public positioning.
4
4
5
-
## Project Structure
5
+
## Positioning: a standard + a reference implementation
6
6
7
-
Cargo workspace with **13 Rust crates** (compile pipeline + bindings) plus a **Python package** (`vectorless/`) that owns the ask/reasoning loop.
7
+
Vectorless is split into two layers that are **independently consumable**:
8
8
9
-
### Rust crates (`crates/`)
9
+
1.**The Rust side defines two standards.**
10
+
-**The IR** (`vectorless-document::Document`) — a single, versioned, serializable artifact that fully represents an understood document. Produced by the compile pipeline; can be persisted, transmitted, and re-loaded.
11
+
-**The navigation primitives** (`vectorless-primitives::DocumentNavigator`) — a fixed set of shell-style operations (`ls`, `cd`, `cat`, `grep`, `find`, `head`, `wc`, `pwd`, `back`, plus inspection and reasoning-index queries) that any agent uses to read an IR. Exposed to Python via PyO3.
├── vectorless-engine/ # Facade (Engine, EngineBuilder) — re-exports public API
25
-
└── vectorless-py/ # PyO3 bindings (compiled into Python native module)
26
-
```
13
+
These two together are **the standard**. Anything that produces a valid `Document` and consumes it via `DocumentNavigator` is a conforming participant.
27
14
28
-
### Python package (`vectorless/`)
15
+
2.**The Python side is one reference agent implementation.**`vectorless/ask/` is a multi-agent system (Orchestrator + Workers + reasoning + verify) that ships in the box. It is the default `engine.ask()` — but it is not load-bearing for the standard. Developers can:
16
+
- Replace `ask/` entirely with their own Python agent built on the same `Document` / `DocumentNavigator` primitives.
17
+
- Skip Python and consume the IR + primitives directly from Rust.
18
+
- Produce IRs from a non-Rust source (the IR is serializable JSON) and feed them into any compatible navigator/agent.
19
+
20
+
The reason this matters: the value of Vectorless is the **IR + primitives contract**, not the bundled reasoning loop. The reference implementation is a courtesy, not a lock-in.
`vectorless-document` and `vectorless-primitives` have no dependency on `compiler`, `llm`, `storage`, or `engine` — by design, so the standard can be consumed without dragging in the pipeline.
67
+
68
+
### Compile Pipeline (the IR producer)
65
69
66
70
The compiler runs documents through four stage groups (`crates/vectorless-compiler/src/passes/`):
67
71
68
72
```
69
-
frontend (parse, build) ← raw bytes → DocumentTree
Every backend pass attaches an optional acceleration field to the `Document`. The IR is valid without any of them (an agent can navigate using only `tree` + `nav_index`); the acceleration fields exist so well-equipped agents can short-circuit reasoning.
dispatch Workers (Rust DocumentNavigator via PyO3)
94
-
→ execute nav commands (ls/cd/cat/grep/find/head/wc/chain)
95
-
→ evaluate(blackboard) → sufficiency check
96
-
→ if insufficient: plan.replan() → loop
97
-
→ rerank/ (dedup → quality score → synthesize)
98
-
→ verify/ → final answer check
94
+
Anyone building a custom agent works against two types and two crates only:
95
+
96
+
```rust
97
+
usevectorless_document::Document; // The IR
98
+
usevectorless_primitives::DocumentNavigator; // The primitive API
99
+
100
+
letdoc:Document=load_ir_from_disk()?; // produced by our compiler, or yours
101
+
letmutnav=DocumentNavigator::new(doc);
102
+
letchildren=nav.ls().await;
103
+
nav.cd("n3").await?;
104
+
letbody=nav.cat(None).await?;
99
105
```
100
106
101
-
The Rust side exposes `DocumentNavigator`(`vectorless-primitives`) and compiled artifacts; the Python orchestrator drives the LLM reasoning loop and calls back into Rust for fast document operations.
107
+
The Python reference agent (`vectorless/ask/`) is just one consumer of this same surface.
102
108
103
109
## Build Commands
104
110
@@ -107,7 +113,7 @@ The Rust side exposes `DocumentNavigator` (`vectorless-primitives`) and compiled
107
113
cargo build # Build all crates
108
114
cargo test# Run workspace tests
109
115
cargo clippy # Lint
110
-
cargo fmt # Format code
116
+
cargo fmt # Format
111
117
112
118
# Build a single crate (fast — only that crate + dependents)
113
119
cargo build -p vectorless-compiler
@@ -199,10 +205,10 @@ When uncertain whether an operation is safe, **default to asking user confirmati
199
205
200
206
## Common Development Workflow
201
207
202
-
1.**Adding compile-pipeline features**: implement under `crates/vectorless-compiler/src/passes/` (frontend/transform/analysis/backend), add tests in the same module.
203
-
2.**Adding reasoning/ask features**: implement under `vectorless/ask/` (Python), add prompts in `prompts.py`.
204
-
3.**Fixing bugs**: write a failing test first, then fix.
205
-
4.**Adding crates**: new modules get their own crate under `crates/`, registered in workspace `Cargo.toml`.
206
-
5.**Python bindings**: update `crates/vectorless-py/src/lib.rs` (PyO3) when Rust APIs cross the FFI boundary; corresponding wrappers go in `vectorless/_internal/`.
207
-
6.**Python SDK surface**: update `vectorless/engine.py` and related modules when the public API changes.
1.**Touching the standard (`document` or `primitives`):** this is a public-contract change. Bump `CURRENT_SCHEMA_VERSION` if the IR's serialized shape changes; document the new field; add tests.
209
+
2.**Adding a compile-pipeline pass:** implement under `crates/vectorless-compiler/src/passes/` (frontend/transform/analysis/backend), wire into the pipeline, attach output to `Document` as an `Option<...>` so old IRs still load.
210
+
3.**Adding/modifying reasoning behavior:** implement under `vectorless/ask/` (Python). This is reference-implementation work, not standard work — it should not require Rust changes.
211
+
4.**Fixing bugs:** write a failing test first, then fix.
212
+
5.**Adding crates:** new modules get their own crate under `crates/`, registered in workspace `Cargo.toml`.
213
+
6.**PyO3 bindings:** update `crates/vectorless-py/src/lib.rs` when Rust types cross the FFI boundary; corresponding Python wrappers in `vectorless/_internal/`.
0 commit comments