Spark self-host path (A + B bootstrap + C)
Destination: Spark hosts Spark — VM and compiler authored as
.spark under selfhost/, not forever hand-written GAS.
Path: A with B bootstrap and C assembler.
This doc is the architecture SoT for the self-host lane. No vapor calendar dates — stages advance when evidence on disk exists.
selfhost/ holds seeds plus a C tokenize aid. Stages advance when evidence on disk exists.
Roles
| Lane | Owner tree | Job |
|---|---|---|
| A | selfhost/ + this doc |
Destination sources: lexer → parser → compiler/VM in Spark |
| B | bootstrap/ or vm/ (peer) |
Thin C VM that runs a growing .spark subset |
| C | sparkasm/ (peer) |
Spark-native assembler (.sasm → ELF .o / .bin) |
GAS asm/*.s → ./spark: disposable scaffold that still runs
today. Not forever authoring SoT. Delete/replace only when B (+ C where
needed) covers the same ops with proof.
Do not start a Rust/Python product VM. Do not deepen “GAS forever.”
Stages (evidence gates)
Stage 0 — Scaffold + A seeds (current)
./sparkELF from GAS still interprets language ops under--dry-run/--live.- Language SoT:
docs/LANGUAGE.md,examples/*.spark. - A seeds under
selfhost/*.sparkdry-run on GAS;lex.cgolden covers mini + ops fixtures. - Gate:
make+./spark --dry-run examples/hello.sparkworks;make test-selfhost-lexgreen.
Stage 1 — Bootstrap B runs a subset ← REAL (advanced)
- Thin C VM under
bootstrap/→spark-bootstrap/sparkc. - Dry-parity (proven):
model/ask/print/let+classify/extract/tool/with/listen/speak/pipeline+review path|text+voicesession +browser run|goto+mitm enable+engine fetchfile://. - Richer ops (e.g.
review url,browser gui/cdp,mitmbeyond enable dry,--liveengine) remain on the scaffold path. - Gate met:
make test-bootstrapgreen (+ classify/tool/review/ voice/browser/mitm parity vs./sparkwhere wired). - See
bootstrap/README.md. Growing A lex seeds does not skip running self-host sources on B.
Stage 2 — Assembler C replaces hand-GAS authoring ← REAL (phase-1)
sparkasmassembles Spark-asm IR → objects/binaries.- Phase-1 proven: push/pop/call/ret/jmp/cmp/test/jcc/add/sub/
and/or/xor/shl/shr/lea/imul/
neg reg(GAS48 f7 df) — not full x86-64. - Gate met:
make -C sparkasm testgreen. Grow further as needed.
Self-host sources run on B
selfhost/*.spark(lexer, then parser, then compiler) execute on B, not only as docs.- Lexer contract proven: tokens for
selfhost/fixtures/mini.spark(and ops) match the seed goldens (seeselfhost/README.md). - Gate: B runs
selfhost/lexer.spark(or successor) end-to-end; Spark-hosted scan matchesexpected_*.tokens.jsonl.
Stage 4 — Spark compiles Spark
- Self-host compiler emits IR or objects (via C assembler / later Spark-hosted assemble).
- Scaffold GAS tree shrinks; product path is A-on-B (+ C).
- Gate: rebuild a known ELF or bytecode from
selfhost/sources without editing GAS by hand. - Not started. Parser/grammar
.sparkfiles are catalogs only.
Stage 5 — Kick the ladder
- Default
./spark(or successor name) is B/self-host built, notas+ldofasm/spark.s. - GAS retained only as archaeological / comparison until removed.
- Gate: owner cutover after Stage 4 proof — not earlier.
What A owns now
| Path | Role |
|---|---|
selfhost/README.md |
Today vs goal; what dry-runs on GAS |
selfhost/token_kinds.spark |
Token kind catalog (dry-run) |
selfhost/lexer.spark |
Lexer algorithm seed (dry-run) |
selfhost/grammar.spark |
Statement grammar catalog (dry-run) |
selfhost/parser.spark |
Parser/AST plan seed (dry-run) |
selfhost/fixtures/mini.spark |
Tiny program for lex golden |
selfhost/fixtures/ops.spark |
Richer: PIPE, review path, NUMBER |
selfhost/fixtures/bootstrap_ops.spark |
Stage 1 B: tool/with/extract/listen/speak/pipeline |
selfhost/fixtures/review_voice.spark |
review path/text + voice{listen/speak} |
selfhost/fixtures/browser_dry.spark |
browser run/goto + mitm enable |
selfhost/fixtures/ide_dry.spark |
ide open/run/ask/show |
selfhost/fixtures/classify_dry.spark |
model + classify (+ multi) + print |
selfhost/fixtures/let_dry.spark |
model + let + print (let KEYWORD) |
selfhost/lex.c |
Real byte lexer (aid until Spark lexer on B) |
selfhost/expected_*.tokens.jsonl |
Goldens for test-selfhost-lex |
make selfhost-lex / make test-selfhost-lex |
Build + golden + dry-runs |
Today A owns catalogs, lexer seeds, and lex goldens — parser and compiler work advances with Stage gates.
Coordination rules
- A does not own
bootstrap//vm/orsparkasm/. - B does not rewrite
selfhost/sources without A. - C does not treat GAS syntax as IR SoT —
.sasmis C’s SoT. - Cross-links only; ops stay aligned with
LANGUAGE.md.
Run (scaffold + seed)
# Stage 0
./spark --dry-run examples/hello.spark
./spark --dry-run selfhost/token_kinds.spark
./spark --dry-run selfhost/lexer.spark
./spark --dry-run selfhost/grammar.spark
./spark --dry-run selfhost/parser.spark
./spark --dry-run selfhost/fixtures/mini.spark
./spark --dry-run selfhost/fixtures/ops.spark
./spark --dry-run selfhost/fixtures/bootstrap_ops.spark
./spark --dry-run selfhost/fixtures/review_voice.spark
./spark --dry-run selfhost/fixtures/browser_dry.spark
./spark --dry-run selfhost/fixtures/ide_dry.spark
./spark --dry-run selfhost/fixtures/classify_dry.spark
./spark --dry-run selfhost/fixtures/let_dry.spark
# Real tokenize today (C aid)
make selfhost-lex
./selfhost/spark-lex selfhost/fixtures/mini.spark
./selfhost/spark-lex selfhost/fixtures/ops.spark
./selfhost/spark-lex selfhost/fixtures/bootstrap_ops.spark
./selfhost/spark-lex selfhost/fixtures/review_voice.spark
./selfhost/spark-lex selfhost/fixtures/browser_dry.spark
./selfhost/spark-lex selfhost/fixtures/ide_dry.spark
./selfhost/spark-lex selfhost/fixtures/classify_dry.spark
./selfhost/spark-lex selfhost/fixtures/let_dry.spark
make test-selfhost-lex
Peer reports when present:
- B:
reports/spark-vm-bootstrap-B-20260831.md - C:
reports/spark-native-assembler-C-20260831.md - A:
reports/spark-selfhost-A-20260831.md