···11+# Schema Discovery Approaches
22+33+Jacquard provides two complementary approaches for discovering lexicon schemas from Rust types:
44+55+## 1. Inventory-Based Discovery (Link-Time)
66+77+**Module:** `schema_extraction`
88+99+Uses the `inventory` crate to collect schema types at link time.
1010+1111+### Pros
1212+- ✅ Fast - schemas already in memory
1313+- ✅ Works with compiled dependencies
1414+- ✅ No parsing overhead
1515+- ✅ Guaranteed to match compiled code
1616+1717+### Cons
1818+- ❌ Only discovers types that are **linked** into the binary
1919+- ❌ Requires creating a custom binary that imports your types
2020+- ❌ Won't see unused types that the linker removes
2121+2222+### Usage
2323+2424+```rust
2525+// bin/extract_schemas.rs
2626+use jacquard_lexgen::schema_extraction;
2727+use my_app::models::*; // ← Must import to link
2828+2929+fn main() -> miette::Result<()> {
3030+ schema_extraction::run("lexicons", true)
3131+}
3232+```
3333+3434+### Best For
3535+- Extracting schemas from your own crate
3636+- When you already have types imported/used
3737+- Production builds where you want to match exactly what's compiled
3838+3939+## 2. Workspace Discovery (Source Scanning)
4040+4141+**Module:** `schema_discovery`
4242+4343+Parses workspace source files directly using `syn`.
4444+4545+### Pros
4646+- ✅ Discovers **all** types in workspace
4747+- ✅ No linking required
4848+- ✅ Works across workspace members
4949+- ✅ Sees types even if they're not used
5050+5151+### Cons
5252+- ❌ Slower - parses all .rs files
5353+- ❌ Doesn't work with binary dependencies
5454+- ❌ Must re-parse source on every run
5555+5656+### Usage
5757+5858+```rust
5959+use jacquard_lexgen::schema_discovery::WorkspaceDiscovery;
6060+6161+fn main() -> miette::Result<()> {
6262+ let schemas = WorkspaceDiscovery::new()
6363+ .verbose(true)
6464+ .scan()?;
6565+6666+ for schema in schemas {
6767+ println!("{}: {}", schema.nsid, schema.type_name);
6868+ }
6969+7070+ Ok(())
7171+}
7272+```
7373+7474+### Best For
7575+- Workspace-wide schema auditing
7676+- Finding all schema types regardless of usage
7777+- Development workflows where you want comprehensive discovery
7878+- When you don't want to maintain import lists
7979+8080+## Comparison
8181+8282+| Feature | Inventory | Workspace Scan |
8383+|---------|-----------|----------------|
8484+| Speed | Fast (runtime) | Slower (parsing) |
8585+| Coverage | Linked types only | All types in workspace |
8686+| Binary deps | ✅ Yes | ❌ No |
8787+| Unused types | ❌ No | ✅ Yes |
8888+| Workspace-wide | ❌ No | ✅ Yes |
8989+| Setup complexity | Medium (need imports) | Low (just run) |
9090+9191+## Hybrid Approach
9292+9393+For best results, use both:
9494+9595+1. **Development:** Use workspace scan for comprehensive discovery
9696+2. **CI/Production:** Use inventory for fast, exact extraction
9797+9898+```bash
9999+# Development: find all schemas
100100+cargo run --example workspace_discovery
101101+102102+# Production: extract linked schemas
103103+cargo run --bin extract-schemas
104104+```
105105+106106+## Future: Schema Generation
107107+108108+Phase 3 currently only **discovers** schemas. A future enhancement could combine
109109+workspace discovery with the derive macro's schema generation logic to actually
110110+**generate** lexicon JSON without needing to link anything.
111111+112112+This would require:
113113+- Extracting schema generation logic from the derive macro
114114+- Calling it directly from the scanner
115115+- Managing dependencies between schema types
116116+117117+Tracked in: [Issue #TBD]