- docs/examples/wo-html: library dep — esc(), element builders,
Tailwind-style utility sheet as one static string, page() shell;
self-contained responses, no CDN/JS/build step
- docs/examples/site: the language tutorial served by the language —
9 seeded chapters in a @table (hello/values+bitwise/containers/
classes/optionals+traps/tables/actors/deps/serving), server-rendered
via wo-html, seed-if-empty so WAL restarts keep admin edits
- routes: / index, /ch/:slug (styled 404), /health, POST /admin/ch/
:slug (bearer handler-side — mechanism framework's, policy app's;
form-encoded title/body update by assignment, 302 back)
- chapter code samples use the lexer's \$ escape to show ${...}
literally; .. never straddles newlines (accumulator style)
- gate: scripts/site-accept.sh + just site — TWO file:// dep remotes,
11 checks incl. authed-edit-survives-restart; /health polling, no
boot-race sleep
- README: run + nginx sketch for writeonce.de; CODE-LOGIC beside code
- full battery 13/13 (site gate included)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- story 34: premise fixed — iteration 36 landed bitwise/hex, digests
and HMAC now expressible in pure .wo; C-builtin vs pure-.wo is the
story's brainstorm call, not an impossibility
- dependency graph: crypto gate names story 34; net-seam gate names
story 35; radix gate corrected — 22 benched the DB, router scan
still unmeasured, perf-targets entry first
- framework README ledger: timeouts/unix/peer rows point at story 35;
ETag row at story 34; path-matching row repointed off iteration 22
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- brings time.ticks builtin (id 84), bench sample + campaign driver
(scripts/db-bench.py), just db-bench/db-bench-quick recipes, first
baseline recorded, story 22 to done/, postgres study cards
- conflicts resolved: board in-progress table (iteration 36 +
framework rows kept, db-bench row now "22 landed"; dangling order
anchor repointed); story 36 moved back to in-progress/ (dir-rename
inference dragged it to done/ — 36 still awaits the manual pass)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- framework README: three rows still said "until fibers/shards" /
"fibers (11)" — now "arc landed 2026-08-21, parked until own slice";
ledger date 2026-08-22
- dependency graph: crypto-fork gate note updated — bitwise + hex
landed with iteration 36, digests expressible in pure .wo; story
34's brainstorm still owns the pure-.wo vs C-builtin call
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- from the guide (docs/guides/database-developer-subagent.md), updated
for the landed slices: wo_idx_probe, perf-targets register, tmpfs
trap, tolerance policy location
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- owns the framework ledger's three seam rows; deadlines compose with
the arc's park plane (POLL_ADD+TIMEOUT fork recorded); framework
knobs explicitly out of scope; stalled-client soak in acceptance
- board + table rows (held seqs bumped); pairs naturally with 24
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- SHA-1 (WS-handshake hard req, RFC 6455 worked example as acceptance),
SHA-256, HMAC-SHA256 over Bytes; hand-rolled C per doctrine, FIPS/RFC
vector fixtures; four forks recorded (namespace, shape, source, file)
- gates chain item 24; digest floor for held 21 + ETag row; 24's
dependency note repointed; board + table rows (held seqs bumped)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- file path IS the wal; dir form byte-identical; one fork (nonexistent
path semantics) leaning recorded; off-chain, driver-only
- board + story table rows (held tail seqs bumped)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- engine: wo_idx_probe answers single-column equality from the index
hash buckets (idx_hash_key1 reproduces idx_hash bit for bit; verify
compares exactly as the slab walk did, so results identical);
composite indexes keep the walk; both executors wired (local + DB
actor RPC)
- compiler: probe_key_of_where lowers "var.col == key" on an indexed
column to DB_PROBE; all where guards still run (guard stays the
final arbiter); keys = ident/int-literal only; Float/Bytes excluded
(engine raw-eq narrower than VM float-eq)
- measured: reads 1.3k -> 1.3M ops/s, p50 600us -> 1us (~x850);
query x830; mixread 1.3k -> 89k s1, 21 -> ~1.9k sN
- gate policy moved into the driver (tolerance_for: refresh-proof);
latency floors max(4x,100us); quick mode skips poll-bound mix
floors; both tolerance classes proven to bite
- proof: test_table wo_idx_probe suite (RED first), corpus
query-index-probe 105/0, full battery green, TSan clean, two
campaigns pass the refreshed baseline
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- constraints-and-grammar: gram.y PK/FK productions, pg_constraint,
RI trigger semantics; writeonce direction — @key as unique alias
(id stays THE key), ref actions (@on_delete), backlink-implies-index
(improves on postgres' not-auto-created FK index)
- indexing-and-point-lookup: AM roster + algorithms (Lehman-Yao,
linear hashing), TID = row address; writeonce gap — probe walks
slabs while idx_bucket exists; O(1) slice direction, non-goals
- card index updated; Rust-era plan-10/11/12 links unlinked (rot)
- docs/guides/database-developer-subagent.md: format, paste-ready
agent definition (doctrine/file map/gates), verification, division
of labor
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- bench/baseline.json: 74 metrics from the first full campaign;
tolerances tuned by a two-run repeatability check (mix* 50%,
read/query 35%, rest 15% — rationale in _config)
- gate bites: --check mode; doctored copy fails, both real runs 74/0
- headline: durable seed 4.5k/s vs ram 297k/s (23's case); reads
O(table) at ~1.5k/s; mixread 1280 vs 21 ops/s single-vs-multi
(the arc's price); msgrate 13.4M vs 2.45M (mutex-inbox number)
- arc delta recorded in story 8; findings in sample README
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Mixer actors: 90/10 read/write, per-actor histograms merged through
the store itself (Hist rows) — exact aggregate percentiles
- msgrate: one-way flood at a worker-placed sink; measured 15.3M
msgs/s same-heap vs 2.06M cross-shard — the mutex-inbox number
- finding: point lookups are O(table) (probe walks all slabs), so
read-heavy mix is quadratic in store size — all-mode calibrated to
N/10 mix ops; the number 22 exists to publish
- TSan clean both shard counts (setarch -R, fibers-gate pattern)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- seed/read/query/write/wal/verify/verify-acked + all (one-process
campaign: RAM store dies with the process)
- per-op time.ticks, 1us-bucket histogram percentiles (reservoir
deviation: no element-write/sort in language; better tail anyway)
- Meta expectation rows ride the same WAL verify checks
- finding: hand-built multi<TableClass> SEGVs on drop (elems classed
OWNED, refs are scalar ids) — worked around, recorded
- finding: reads ~1.6k/s p50 595us vs 287k/s inserts — probe walks
all slabs; the number 22 exists to surface
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- worker DB builtins marshal to shard 0: requester-side slot encode
(VM heaps never read cross-shard), owner executes serialized in
adopt, reply unparks via new WO_PARK_INBOX park + envelope 3/4
- engine gains thread-agnostic slot entry points (insert_slots,
update_field_slot, val_encode/clone, wo_db_exec_req); traps and
messages byte-identical to the local path
- main.c: engine + replay boot BEFORE shards spawn; workers assert
rt.db/rt.wal NULL; busy shard adopts inbox once per slice
- latent stage-1 bug fixed: shared io_uring params static raced by
lazy worker init lost park wakes (~1/20 hangs); params per-vm,
short submit now fails loud
- new sample docs/examples/db-actor + just db-actor gate 8/0 (multi
x3, uring/epoll forced, single byte-exact, WAL replay pair);
ASan+TSan 6/6; full battery green
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- five-property map in marker doc: atomicity/durability/recovery
proven or held (18); concurrency control = stage 3's property;
space reclamation RAM done (slot reuse), disk = new story 32
- story 08: three stage-3 criteria (one commit per write RPC +
ack-after-owner-fsync, workers WAL-free + replay-before-serve,
no torn reads under TSan corpus); arc plan stage 3 carries them
- refine/32-wal-checkpoint.md: snapshot + truncate, bounded replay,
crash-during-checkpoint safe; four forks; after 23
- chain now stage 3 -> 22 -> 31 -> 24 -> 23 -> 32 in all 10 docs;
boards + seq bumps synced
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- 08 landed in discarded/ by mis-drop, swept into prior commit with
two dead links; corrected to stories/.../in-progress/ per intent
- 11 joins it (one arc, active slice)
- board doctrine: active stories bucket named; all links re-verified
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- one marker doc, deleted on landing; board doctrine names the
second folder exception
- board In-progress row was stale (nothing active + dead anchor);
now points at marker + arc plan tasks 7-8
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- io_uring is a must; epoll approach discarded (developer decision)
- plan superseded by shard-fiber-arc plan of record; banner + row in
plan/discarded.md; file kept as idea reference
- three live pointers repointed: status language-track row 8,
principles enforced-by, story 08 note
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- code-verified ready: arc stages 1+2 merged to master; stage 3
concrete in plan (tasks 7-8); rt.db set on primary only
(main.c), worker_late_init memsets rt — WO_T_DB hole real
- 22/23/24/31 stay in refine/: open forks, no bench harness,
no crypto builtins, chain-blocked
- links fixed both directions; board doctrine names hold/ bucket
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- iterations 18/25/26 marked hold in their spec + plan headers
- 25's story file removal committed; plan doc stays for resumption
- web-framework spec's relates-to flags 25 held
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Float full stack: literals (fraction/exponent; `0..10` still a range), f64
opcodes 34-41, @table column, WAL bit-exact replay, json fractions in and
shortest-round-trip out. IEEE-quiet — FDIV never traps where DIV does.
- Bytes: a wo_str with its own class id, so alloc/free/copy are shared but no
Text builtin accepts one; len/at/slice/eq/concat, base64 both ways, json
boundary as base64; TEXT_COPY preserves the kind.
- No implicit Int/Float mixing (WO-E201 in the typechecker, not the emitter,
which picks the opcode from one side and would misread the other).
- One IEEE deviation: float_cmp total order (NaN last, -0.0 == +0.0) for
indexes and order-by, keys canonicalized to match. `?Float` nil is a
reserved quiet NaN — the zero word is +0.0, WO_NIL_SCALAR's bits are -2.0.
- Renderer prefers fixed over exponential in 1e-6..1e21: pure shortest makes
a price of 900.0 read `9e+02`. One renderer for interp/json/float_to_text.
- Fixed en route: lexer double-counted the leading digit; is_scalar_shaped
took Float/Bytes as Int-shaped; Bytes ownership needed a shared heap-scalar
predicate or temps never dropped; order-by bit-compared negatives backwards.
- Iteration 17: `kind = "library"` (absent = program; bad value = WO-E109),
entry-less check mode retiring the `--emit` workaround, Go's `internal/` as
WO-E108 at the consumer's `use`. Driver-only; VM/.wob/GC untouched.
- Framework reorg: internal/{parse,serve}.wo; http/form.wo split out to keep
media_type/form_values public (parse.wo had grown public surface).
- Docs: link audit (97 -> 88 broken, conflict markers resolved, 2 duplicate
stories removed), 00-code-review verified 26/27, iterations re-sequenced.
- Also carries the pre-staged pub(read)/using/#if work from the index.
- Gates: corpus 103/0, test_wal 156/0, web-app 26/0, oop-accept ALL MET.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- developer directive: pending iteration IDs now ARE the priority order;
LANDED iterations keep historical numbers (code comments and commit
history cite them — records, not a queue); 8/11 (the half-landed
arc), 17 (parked, artifacts on a branch), 18 (next, artifacts named)
also frozen
- mapping (recorded in 00-story): 19<-20 Float+Bytes, 20<-9c attach,
21<-9d keypair, 22<-9e benchmarks, 23<-9f io_uring WAL, 24<-19 chat,
25<-10 services, 26<-12 blue-green, 27<-9g query corpus,
28<-14 skillhost, 29<-13 metaprogramming
- 11 story files renamed; every doc reference re-numbered (word-boundary
sweep for the lettered 9x ids, phrase-level for numeric ones); the
iterations table rewritten with Seq == priority and "(was N)" notes;
story-scoped link check: zero broken
- merge-recovery folded in: the partial master merge had dropped the
chat story, the fibers exploration note, the arc spec+plan, the
framework-v2 plan, and the iteration-17 spec+plan — all restored from
their branches and renumbered consistently
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- brainstorm settled four forks: Float FULL STACK in one iteration
(literal, IEEE f64 VM ops via u64 bitcast, @table column + WAL slot,
json fidelity — json.c's own comment names the hole: fractions are
malformed because "the language has no [float]"); IEEE-754 QUIET
semantics (division never traps, NaN flows; Int keeps DIV0; no
implicit mixing — float(i)/trunc(f) bridges); BYTES ships alongside
(binary carrier: multipart files, WS frames for 19, crypto digests;
Text goes back to meaning text); iteration 20 + spec before code
(.wob/WAL version bump earns a written spec)
- the rest of the missing-type survey recorded with reasons: Result/
Option expressible today (?T + payload unions), tuples covered by
records + doctrine, Decimal stays cents-until-a-workload, Char/
Unicode its own future story, Set/ADTs parked post-12, scalar
newtypes need the rejected `abstract`
- one indexed-storage deviation from raw IEEE spec'd loudly: a Float
index needs a total order — NaN sorts last
- board row, story-table row (seq 26), graph node (9+16 -> 20 -> 19;
crypto gate wants Bytes)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- spawn placement: round-robin across shards (same-shard when the
engine is absent/single); the actor's mailbox and delivery belong to
its HOME thread — a spawn to another shard travels as an ADOPT
envelope, a send as a SEND envelope (mutex-guarded inbox + eventfd
wake; the spec's lock-free rings stay a disclosed deviation until
9e measures the mutex)
- workers: first envelope triggers lazy full-vm init UNDER the inbox
mutex (TSan caught the memset racing a concurrent push, twice — the
second was inbox_push reading wake_efd outside the lock; both fixed,
gate x8 + battery clean); serve loop = adopt -> run to drained ->
wait on the plane (the wake eventfd is watched by io_uring POLL_ADD
oneshot / epoll level-triggered on BOTH backends)
- ownership across heaps: every allocation stamps rt->shard_id into
the header (the field reserved since iteration 2); a drop on the
wrong shard routes home as a FREE envelope — the owner's arena stays
single-threaded by construction; at teardown routed frees become
no-ops (arenas die wholesale) which is what un-danced the freed-mutex
ASan SEGV the first ordering had
- WO-E222: an actor's state or message type that is (or transitively
contains) an inferred-traced class refuses at the spawn/send — with
round-robin every actor is potentially remote; corpus-pinned
(compile-fail/traced-send, inference-aware: Box contains ?Node)
- determinism narrowed per spec: oop-e2e pins WO_SHARDS=1 (exact
outputs); the fibers gate grows multi-shard SET assertions + a TSan
run (wovm-tsan target; setarch -R fallback for kernel 6.5+ ASLR)
- NEXT_RUNNABLE honors engine shutdown for parked workers (deadlock
hole closed); io_wait's adopt-wake (rc 1) no longer reads as fatal
- battery: oop-e2e 93/0, fibers 10/0 x8 (+WO_IO=epoll), log-watcher
7/0, employee 8/0, web-app 21/0, deps 8/0, runtime tests 16/16
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- wo_engine + wo_engine_start/stop: one pinned pthread per extra core
(pthread_setaffinity_np); shard 0 is the primary (entry + database);
workers idle on a wake eventfd until fibers arrive (T6) or shutdown
- default = all cores (the arc's brave landing), WO_SHARDS=1..64
overrides; N=1 spawns no threads — byte-identical to stage 1
- worker vms are LAZY: identity + wake fd only until their first fiber
arrives — 20 idle shards must not cost 1.25 GiB of eager arenas
(they did: the web-app gate flaked on exactly that before the fix;
3 consecutive green runs after)
- engine stops (join + destroy) before the primary's teardown
- battery at the 20-core default: oop-e2e 92/0, fibers 8/0,
log-watcher 7/0 (+WO_SHARDS=1 identical), web-app 21/0 x3,
employee 8/0, deps 8/0, runtime tests 16/16 files green
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>