docs: phase-0 — OQ-GN-01 resolved: dev tool, static files, module output

- clarification: alkcall is a library others build on; alkgen branches
  1+2 are a dev tool generating static files into downstream projects
  (protocol crates alktty/alktunnels/sftp, cloud integrations vast.ai/
  runpod) from provided schemas (BAST or jsonschema/openapi)
- OQ-GN-01 resolved: module-level output for v1; fragments out
  (defeats dev-tool purpose), crate generation out for v1 (composed
  from modules later if asked). Residue: file partitioning policy
- OQ-GN-06 reframed: generated files land in projects that don't
  depend on alktype today, so dependency footprint is consumer's
  choice, not wire-shaped; leaning self-contained, POC decides
- branch 2 reframed: static counterpart of alkhttp from_* adapters
This commit is contained in:
2026-09-08 08:58:50 +00:00
parent 0e9bdf65ab
commit 79c2794a99
+57 -32
View File
@@ -13,16 +13,19 @@ approach."* It is the input to Phase 1 (Architecture).
Drafted 2026-09-08 from the initial setup discussion and a survey of
the four relevant references (below). The crate is the codegen engine
of the alk* stack: handlebars-rust templates rendered over alktype
BAST documents, producing code artifacts. Three branches, roughly in
of the alk* stack: a dev tool generating static files into downstream
projects from schema documents — handlebars-rust templates rendered
over alktype BAST documents (branch 1) or jsonschema/openapi documents
(branch 2), producing code artifacts. Three branches, roughly in
timeline order:
1. **BAST readers/writers/validators**generate the binary
read/write/validate code alkcall's channels consume, from alktype
BAST documents. The primary v1 target.
2. **Call-protocol handlers** — generate handlers in the shape of
alkhttp's `from_openapi` / `from_jsonschema` adapters for alkcall's
call protocol (JSON RPC). Second.
1. **BAST readers/writers/validators**from alktype BAST
documents, generate static binary read/write/validate code
integrating with alkcall's channels. The primary v1 target.
2. **Call-protocol handlers** — generate the boilerplate for
call-protocol (JSON RPC) integration, from jsonschema/openapi
(or BAST) inputs — the static counterpart of alkhttp's
`from_openapi` / `from_jsonschema` adapters. Second.
3. **Template-JIT core** — an alkminer-v1-shaped render-then-compile
cache with partials. Far down the timeline; influences only how
general the core template layer must be. Not a v1 requirement.
@@ -33,8 +36,8 @@ timeline order:
provides the BAST document model (`Schema`/`Definitions` builder
types, `AlkTypeKind`, `OffsetMap`, `PackedLayout`, `read_plan`,
`validation_plan`); alkgen owns template assets, context building,
registry construction, and rendering. Output is code text (Rust for
v1).
registry construction, and rendering. Output is static code files
generated into downstream projects (dev-tool model — OQ-GN-01).
- **wasm-clean is validated, not assumed.** The skeleton (alktype
0.3.0 + handlebars 6.4 + serde_json preserve_order + thiserror)
compiles to `wasm32-unknown-unknown` release as-is. handlebars-rust
@@ -123,23 +126,32 @@ Numbered OQ-GN-01.. for reference and promotion to
### OQ-GN-01: What is alkgen's primary unit of output — a crate, a module, a fragment?
Options in increasing size:
**Resolved 2026-09-08 (setup discussion): static files generated into
a consumer project.** The clarification that resolved it: alkcall is
a *library* others build on, and alkgen's branches 1 and 2 are a
*dev tool* — it generates boilerplate into some downstream project
(protocol crates like alktty/alktunnels/sftp, cloud-provider
integrations like vast.ai/runpod), not into alkcall itself. Both
branches take a provided schema document (BAST or jsonschema/
openapi) and emit static files.
- **Fragment**: a function or impl block rendered per type/document;
the consumer assembles files/crates (most composable; the consumer
owns imports/module layout).
- **Module**: a self-contained `.rs` file (readers.rs, writers.rs,
validators.rs) with banner + use statements (typebox-rs
`generate_module` precedent; alkcall consumes a file directly).
- **Crate**: a full Cargo.toml + src tree generated into the
consumer's workspace (most turnkey; heaviest maintenance burden).
- **Fragment** is out — the consumer assembling fragments by hand
defeats the dev-tool purpose.
- **Crate** is out for v1 — generating a whole Cargo project is
trivially composed from modules later if a consumer asks, and
would bake build-layout decisions (workspace placement, dep
versions) into the generator prematurely.
- **Module-level output is the v1 shape**: one document → one or
more self-contained `.rs` files (banner + use statements +
impls), dropped into the consumer's `src/` tree. Matches
typebox-rs `generate_module` and how generated protocol files
would sit in e.g. an alktunnels-style crate.
Half-hunch: module-level output with fragment-level API (render one
document → one module file), because alkcall's channels want a
drop-in file and crate generation is trivially composed from
modules later. But this is a wire-shaped decision (generated file
layout is stable once a consumer exists) — needs alkcall-side
discussion before Phase 1.
Residue for Phase 1: file partitioning policy (one file per
document vs per-type files; where the reader/writer/validator
split lands), and whether generated files are regenerated wholesale
(overwrite) or support partial regeneration. These are spec-shape
tasks, not research questions.
### OQ-GN-02: Interpretation depth — render from BAST directly, or from alktype's plans?
@@ -233,11 +245,18 @@ before Phase 1 ADR — likely the first POC if any.
### OQ-GN-06: Does branch 1 output depend on alktype at all?
Related to OQ-GN-05: if generated code is self-contained (a), it
should not `use alktype` at all — alkgen becomes a build-time dev-
dependency of consumers. If delegating (b/c), generated code links
alktype at runtime. Wire-shaped decision (imports in generated
files are stable once consumed).
Related to OQ-GN-05. Reframed 2026-09-08 by the dev-tool model
(OQ-GN-01 resolution): generated files land in *downstream projects*
which do not currently depend on alktype — so a self-contained (a)
output makes the generated module dependency-free, while a
delegating (b/c) output adds alktype as a runtime dep of the
consumer project. That is a real cost the consumer weighs, but no
longer wire-shaped in the old sense: the consumer's Cargo.toml is
their file, regenerated output can bump deps without a wire break.
The decision now rides mostly on OQ-GN-05's performance trade (every
runtime call into alktype keeps the compiled path interpreter-
shaped) plus consumer taste on dependency footprint. Leaning (a)
self-contained for branch 1; the reader POC decides.
### OQ-GN-07: Validation strategy in generated code
@@ -316,13 +335,19 @@ is a place the compiled path stays interpreter-shaped.
alkhttp adapters (§Prior art)
- [x] Branch scope framed — readers/writers/validators first,
handlers second, JIT later (§opening)
- [ ] OQ-GN-01 (output unit) — resolved with alkcall-side input
- [x] OQ-GN-01 (output unit) — resolved 2026-09-08: static files
generated into downstream projects (dev-tool model); module-
level output for v1, fragments and crate-generation out.
Residue: file partitioning policy (Phase 1 spec task)
- [x] OQ-GN-02/03 (context source, duplication cut) — direction set
2026-09-08: plan-driven contexts (plans for offsets/sizes, BAST
for descriptive metadata); duplication resolved as posture.
Residue: exact plan→context projection (Phase 1 spec task)
- [ ] OQ-GN-04 (language scope) — low-stakes; core language-agnostic,
Rust-only templates for v1 (half-hunch, acceptable to defer)
- [ ] OQ-GN-05/06 (delegation boundary, dependency shape) — the
reader-POC cluster
reader-POC cluster; leaning self-contained output (a), POC
decides
- [ ] OQ-GN-07 (validation strategy) — resolve with or after
OQ-GN-05
- [ ] OQ-GN-08 (POC decision) — run POC 1 or record why analysis