- 01: crate scaffolding - 02: event loop epoll - 03: hand-rolled HTTP - 04: tokio/axum cutover
5.2 KiB
01 — Scaffolding the Crate Tree
Context sources: ../../CLAUDE.md, ../../README.md, ../../crates/README.md, ../runtime/database.md, ../runtime/database/07-wo-seg-migration.md.
Goal
Lay out the full crates/ directory tree that the 7-phase .wo runtime design implies, without moving any active code. Every target crate the design docs name gets an empty-but-compilable home so that:
- every doc reference to
ql,wal,policy, etc. resolves to a real directory - each phase's extraction work (move X out of
rtinto its target crate) is a mechanical copy into an existing skeleton rather than a net-new crate creation - IDE workspace views, dependency graphs, and
cargo docshow the project's intended shape on day one
Design decisions (locked)
- Scope: all 7 phases. 14 new empty library crates covering Phases 2 → 6 land in one pass.
rt(already shipping Stage 2) is the 15th. rtstays monolithic. Today's Stage 2 code — lexer / parser / AST / compile / engine / server — stays insidecrates/rt/and continues to satisfy the 14 existing unit tests. Code migrates into the new crates as each phase activates, not in this pass.- Contents:
Cargo.toml+src/lib.rsdoc-comment only. Eachlib.rsis one module-level//!doc block pointing at the phase doc, naming the responsibilities, and flagging which modules inrtmigrate here later. No placeholder types, no stub traits. - No
wo-prefix. New runtime crates areql,value,engine, etc. — notwo-ql,wo-value. The prefix is redundant inside the project's ownwonamespace and noisy in imports (use ql::Parserbeatsuse wo_ql::Parser). The v1 crates in.dev/reference/crates/keep theirwo-prefix — the distinct prefix makes the v1/v2 split visible at a glance. - Workspace membership: root
Cargo.tomllists every new crate as a member..dev/reference/cratesstaysexclude-d (nested workspace, separate v1 code).
Rationale and alternatives considered: see ../../CLAUDE.md "What's in rt today vs. what the empty crates promise" and the recorded AskUserQuestion answers that preceded this plan.
Crate map
All names are stable — documented in ../runtime/database/07-wo-seg-migration.md (Phase 2–5) and derived from ../runtime/database/06-lowcode-fullstack.md component tables (Phase 6).
| Phase | Crate | One-line purpose |
|---|---|---|
| 2 | ql |
.wo grammar — lexer, parser, AST |
| 2 | value |
tagged Value + dotted-path helpers |
| 2 | engine |
in-memory executor (rel / doc / graph) + schema catalog |
| 2 | txn |
transaction coordinator — MVCC, RETURNING alias table |
| 2 | db |
top-level facade — open(), Tx, Query, Subscribe |
| 3 | wal |
write-ahead log — io_uring + fsync + recovery |
| 4 | sub |
live subscriptions — delta frames on commit |
| 4 | http |
wire protocol — REST / GraphQL-over-WS / native codec |
| 5 | gen |
codegen — .wo type → Go / TS / Rust / Python clients |
| 6 | policy |
RBAC + row-level rules compiled into planner rewrites |
| 6 | logic |
on <event> triggers + fn ... in txn interpreter |
| 6 | service |
service rest/graphql/native endpoint dispatch |
| 6 | ui |
##ui screens → SSR HTML + client runtime |
| 6 | app |
##app route manifest + startup hooks |
| — | rt |
existing — Stage-2 monolith + the wo binary |
Status
✅ Done. All 15 crates exist, the root workspace members list includes them, cargo build and cargo test --lib both pass, and cargo run --bin wo -- run docs/examples/blog still serves the blog sample (Stage 2 behaviour unchanged).
| Artifact | Status |
|---|---|
14 new crate skeletons (Cargo.toml + src/lib.rs) |
✅ |
Root Cargo.toml lists all 15 crates as members |
✅ |
crates/README.md with the phase-mapped inventory |
✅ |
cargo build at root (compiles 15 crates) |
✅ |
cargo test --lib at root (14 existing rt tests) |
✅ |
cd .dev/reference/crates && cargo build && cargo test (v1 still green) |
✅ |
cargo run --bin wo -- run docs/examples/blog (Stage 2 still serves) |
✅ |
Non-scope
- No code extraction. Moving
lexer.rs/parser.rs/engine.rsout ofrtintoql/engineis explicitly deferred. That happens incrementally as each phase activates. - No
genbinary target.genships as a library-only crate in this pass. The[[bin]]lands when Phase 5 starts. - No test scaffolding. The empty crates don't get unit-test stubs. When a crate gets real code, it gets real tests.
- No cross-crate
pub usereexports fromdb. The facade crate documents its future surface in its doc comment but doesn't import anything yet.
After this plan lands
Next planning documents in this directory should describe the first real extraction — likely 02-extract-ql.md when Stage 3 begins and the subscription engine needs the parser from a second call site. Until then, the 14 placeholders sit unmodified alongside rt.