- done/ (11): 1, 2, 3, 4, 6, 7, 7b, 9, 9b, 15, 16 — landed iterations
(9/9b remainders live in the post-12 drain list, not in the files)
- refine/ (8): 9c, 9d, 9e, 9f, 9g, 11, 13, 14 — everything marked
"no spec yet / brainstorm before planning"
- root keeps: 00-story (index), 05 (partial, plan 8 open), 8/10/12
(specs or plans exist), 17 (parked, spec+plan approved), 18 (next)
- every cross-reference re-pathed and VERIFIED resolving: board, specs,
plans, employee-list README, story table, intra-story links (moved
files' relative links deepened one level; done/7b's 9e pointer now
crosses to refine/)
- pre-existing dead link noted, not touched: refine/11-fibers.md points
at docs/plan/exploration/fibers/00-fibers.md which does not exist
(predates the move)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 00-story.md iterations table rows reordered into implementation order
with a Seq column; # stays an immutable ID (files never renumber —
every board/spec/plan references by number)
- order: 1-7b, 9, 9b, 15, 16 (landed, landing order) -> 18 NEXT (spec
approved) -> 9c -> 9d -> 9e -> 8 -> 9f -> 11 -> 10 -> 12 -> 9g -> 14
-> 13; 17 parked row at the end, slots anywhere after 16 on directive
- story note + board implementation-order list synced (18 inserted as
item 2 after the parked-17 note; 9g now explicitly before 14; list
renumbered)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- framework README core checklist expanded into the v1 STATUS LEDGER:
seven categories (transport, routing, request/response, context &
middleware, storage integration, security, crypto), every item
marked done / partial-with-named-gap / candidate / parked-behind-8-11
/ needs-runtime-seam
- verified before labeling: BODY_MAX caps headers AND body (size limits
done); net has no timeout or unix-socket or peer-address surface
(runtime seams); language has NO bitwise operators, so SHA/HMAC/CRC32
must be C runtime builtins or bit ops land first (fork to brainstorm);
radix routing waits for 9e to measure the linear scan first
- crypto hard stop recorded: HS256 unlocks and nothing past it
- memory-rich features relabeled FRAMEWORK V2 = iteration 18 (story +
spec banners + board rows); v1 gaps land as slices per the ledger
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- App.get/post/put/delete_(pattern, take h: Handler) — the take-interface
shape probe-proven release + ASan before landing; retires plan-16
deviation 1; delete_ because delete is the query keyword
- dispatch matches path-first: wrong method on a known path answers 405
with Allow in registration order; unknown path stays 404
- HEAD routed as GET, body suppressed, Content-Length names the body a
GET would carry (serialize gains head_only)
- Logging middleware (request line to stderr) ships in router/
- set_header(mut r, name, value) — the builder escape hatch
- web-app registers through the helpers (dogfood); README documents all
- gate grows 14 -> 16: 405+Allow, HEAD-vs-GET content-length equality
- all gates green: web-app 16/0, woc-test 540/0, oop-e2e 89/0,
deps-accept 8/0, log-watcher 7/0, employee 8/0
- board/story: iteration 17 parked (spec+plan ready on library-internal),
16 carries the v1-polish landing, order list updated
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- NEXT PLAN rewritten: iteration 17 is the goal slice (merge branch, spec/
plan, kind = "library", internal/ WO-E1xx, framework reorg, gate list)
- previous NEXT PLAN retitled "Landed 2026-08-15 — the executable milestone";
all six measured items were already done, board rows were stale
- board row 7: in-progress -> landed 2026-08-15 (ASan-clean, SIGTERM, fd-flat,
soak, just log-watcher 7/0); iteration 07 story banner updated to match
its plan doc's done banner
- in-progress table now carries iteration 17 spec/plan
- implementation order re-sequenced for framework goal: 17, 9c/9d, 9e, 8,
9f, 11 (+ h2c unparks), 10, 12, then 14/9g demoted (skillhost no longer
the driving workload), 13 + parked drain last
- story notes record the shift and the new order
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- new "Implementation order (sequenced 2026-08-20)" section in 00-status.md
pending bucket: 7-finish, 17, 9g, 14, 9c/9d, 9e, 8, 9f, 11, 10, 12,
13 + parked drain
- forcing rules recorded: 9f after 8+9e; 9c precedes 10; 9d folds into 9c;
12 after 9+10; 11 rides 8's scheduler; h2c behind 8/9f/11; post-12 park
directive unchanged
- 9e placed before 8 so restructure/perf work has a signed baseline
- 14 early as next driving workload (stdlib-shaped, shard-independent)
- story 00-story.md notes point at the sequenced list
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- fork 1: library-ness manifest-declared, kind = "library", default program
- fork 2: privacy = Go internal/ directory rule, named diagnostic at use
- fork 3: dep-boundary-only scope; Go subtree rule recorded as later tightening
- fork 4: lib+bin dual — library default action is check, explicit build works
- Go-inherited rule pinned: internal type in public signature allowed, no check
- impact analysis added: framework loses --emit workaround, plumbing under
internal/; compiler = two seams (driver kind + dep-use refusal WO-E1xx)
- VM zero impact by construction: no .wob change, libs compile whole-program
into consumer image, internal modules still emitted (privacy strips nothing)
- GC zero mechanism impact; pinned: inference stays whole-program, app usage
can promote dep classes, internal/ invisible to gcinfer — intended, not bug
- board + roadmap rows: needs-refinement -> forks settled, spec/plan next
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brainstorm outcome, deliberately NOT implemented (developer decision: keep
as an iteration needing further refinement). Records:
- the two gaps iterations 15/16 exposed: library-ness is implicit (a
no-main project fails woc <dir> build mode — the framework is verified
via an --emit workaround) and the dep boundary leaks internals (pub has
no dep-private tier: parse_request is as importable as Handler).
- the conventions corpus: Go (package decides program-ness; cmd/;
internal/ = directory-shaped privacy, zero keywords) vs Rust ([lib]/
[[bin]] manifest targets; pub(crate)-family keyword visibility). Doctrine
fit points at Go's shape with an explicit manifest key (writeonce HAS a
manifest; explicit beats inference in errors).
- four open forks for the spec: kind declaration form; internal/ vs
pub(lib) vs export-allowlist; dep-boundary-only vs Go's subtree rule;
lib+bin duality. Draft acceptance criteria; web-app 14/0 as the
regression gate. Roadmap + board rows added.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Brainstorm outcome (forks locked with the developer):
- TLS: proxy-terminated (nginx/caddy gives browsers TLS+ALPN+h2; the
framework speaks HTTP/1.1 behind it) — zero TLS in the toolchain, no
doctrine fight; homegrown TLS refused outright.
- Dependencies: a real mini package manager — wo.toml [deps] with exact-rev
git deps, wo.lock, .wo-deps cache, `use <dep>` as a module root; fetch by
shelling to the git binary (no network code in woc); flat-only v1.
- HTTP/2: v1 is HTTP/1.1 keep-alive; h2c is the parked successor behind
iterations 8/9f/11 (multiplexing needs a scheduler to pay off); the
bytes/buffer type rides with it, not v1.
- Handler model: no function values by doctrine, so Handler/Middleware are
structural interfaces (ICALL dispatch, WO-E205-checked); middleware returns
?Resp and rides the shipped ?T narrowing.
- Incubation: framework at docs/examples/writeonce-framework/, consuming
storefront at docs/examples/web-app/ importing it THROUGH [deps] — the
sample exercises fetch -> lock -> build -> serve -> durable-restart.
- Iteration 10 relationship: service blocks later LOWER ONTO this library.
Files: specs/2026-08-18-web-framework-design.md (A deps normative, B
framework normative, C h2c parked); stories 15-deps-package-manager.md +
16-web-framework.md; roadmap + board rows.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- frames a writeonce port of ~/projects/skillhost (C++ MCP host that
links libllama in-process, discovers filesystem skills, runs their
scripts confined) as the sample that drives host capabilities into
the open — the way log-watcher drove the systems stdlib
- names each gap as a candidate iteration (surveyed 2026-08-16 vs the
running compiler + skillhost source):
- Blocker A: in-process native-lib FFI (no FFI today) — fork:
FFI-as-language vs out-of-process model driver over proc/net+json
(llama-server, needs nothing new); leaning out-of-process
- Blocker B: stdio transport — no stdin/stdout builtins; port uses
a TCP socket meanwhile; io.stdin_read/stdout_write a candidate
- Blocker C: bounded/killable subprocess — proc.run has no timeout/
signal/process-group kill; smallest + most broadly useful, do 1st
- partials: recursive fs walk, exec-bit check, symlink-resolving
confinement (realpath) — one small fs-metadata iteration
- records what is already expressible (catalog via @table/9g skill-
catalog, discovery, frontmatter text-parse, config, single-thread
serve, context-gate arithmetic — no VRAM query needed)
- out of scope: in-process libllama/CUDA, VRAM introspection, exact
sampler chain / per-turn memory clear
- roadmap + board rows added
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- method: an embedded-SQL app is a grammar corpus; catalogue what it
actually uses and add only that, translating its statements 1:1 as
the acceptance (the postgres/System.Linq reference pattern applied to
a whole application)
- corpus #1 = ~/projects/skillhost (C++ MCP host, embedded SQLite skill
catalog): surveyed, entire SQL footprint is one file — 1 table, a
single-row parameterized INSERT, 4 SELECTs. 3 of 5 statements already
run on the 9b surface (insert, where name==?, order by name; PK ≈
@unique). Exactly 2 are the real gap:
- whole-query `count` (group-free; the degenerate aggregate, NOT
the parked group-by)
- correlated `not exists` subquery (skillhost's roots-of-the-tree)
- notable finding: skillhost's NOT EXISTS is naturally a `backlink`
emptiness in writeonce (children backlink + len==0), so the corpus
may be fully expressible once len(query) is confirmed — the iteration
may collapse to "confirm len(query) + add exists"; forks record this
- explicitly parks everything skillhost does NOT use (join/having/
offset/distinct/CTE/window/union/upsert/returning/json/fts/triggers)
and the full group-by; each enters only when a corpus demands it
- acceptance: docs/examples/skill-catalog mirroring skillhost's schema
+ its 5 catalog ops as writeonce translations
- roadmap + board rows added
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- captures the toCSV/reflection thread: principle 13 forbids runtime
reflection, so a generic serializer can't be a user-written function;
Rust answers with derive macros (compile-time codegen), and
json.encode is already a single hand-built instance of exactly that
- iteration generalizes json.encode's mechanism into a reusable derive
facility: @derive(Json/Csv/Eq/Hash/Show) -> the compiler generates
per-type routines from the class-table metadata it already emits,
monomorphic, no runtime type tag, no dynamic dispatch
- closes the query-result-serialization gap
(csv.encode(from e in Employee ... select e)) that has no expression
today; acceptance requires json.encode retrofitted onto the framework
with byte-identical output, and disassembly proving no reflection
- four forks: request surface (lean @derive annotation), invocation
(lean compiler-recognized encode builtins, no UFCS/methods), Eq/Hash
sharing the engine's key comparison, static applicability checking
- out of scope: full trait/typeclass system, user proc-macros, general
generics, cross-channel derive -- a CLOSED compiler-known derivable
set, the pragmatic 80% without the type-system weight
- numbered 13 to echo the principle it lives inside; roadmap + board
rows added
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- 9e durability/throughput/scale: the measurement backbone -- run the
employee program, restart to prove persistence, benchmark read/write
through compiled .wo, ~1M-row mixed load with throughput floor + p99
ceiling + flat RSS; the gate every optimization signs (before/after
delta required, no measured delta = not accepted)
- 9f io_uring group-commit: replace fsync-per-commit with batched
io_uring durability overlapped on shard threads; same ack-after-
durable contract, crash battery unchanged, automatic fsync fallback
on kernels without it; deliberately LAST (needs 8's threads to
overlap and 9e's baseline to beat)
- wired the existing levers into the arc: iteration 8 (thread-per-core)
= "optimize multithreading", 7b (mark-sweep) = "implement GC" --
each now gated by re-running 9e and recording the delta
- explicit sequence recorded in 9e: 9b lands -> 9e baseline -> 7b
re-bench -> 8 re-bench -> 9f re-bench
- roadmap + board rows for 9e/9f; four forks each for the specs
(load generator, absolute vs relative budgets, what "1M" means,
durable vs RAM headline; ring model, liburing vs raw, batch
boundary, fallback testing)
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- promotes 9c's identity fork to its own iteration: program identity
is a keypair (first-boot generated into WO_DATA, 0600, printable
fingerprint); A's [share] grants name PUBLIC KEYS, B pins A's key
in [connect.a]; mutual challenge-response, fresh nonces, transcript-
hash signing (protocol tag + fingerprints + nonces + channel)
- acceptance criteria: registered-key attach carries 9c rights
unchanged; unregistered key refused pre-statement with fingerprint
logged; same-uid-wrong-key refused (uid SUPERSEDED, not
supplemented); impostor on A's socket path aborted by B's pinned-key
check; handshake replay refused; rotation = manifest change
- four forks recorded: crypto provenance (lean: vendored compact
Ed25519 as the one sanctioned vendored component), keygen home
(lean: first-boot into WO_DATA), signed-transcript layout, uid
survival (lean: keys only, peer-cred demoted to log enrichment)
- out of scope: transport encryption, CA machinery, key escrow,
root-attacker protection
- plan folds into 9c's when specced (neither ships alone); 9c fork 3
marked superseded-as-end-state; roadmap + board rows added
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- program B attaches to running program A's persistent database via an
IPC string in B's wo.toml [connect.<name>]; A registers clients by
name with read / read+write rights in its [share] manifest section;
unregistered = refused at connect, under-privileged = catchable trap
- doctrine preserved: A stays the single writer -- B's statements
execute inside A through the same choke-point row API, B never
touches A's WAL or slabs; typed statements checked by B's compiler
against A's table shapes, schema handshake at attach
- four forks recorded for the spec: channel carrier (lean: unix
socket + SO_PEERCRED), how B's compiler learns A's shapes (lean:
project reference + live handshake), grant granularity (lean:
whole-db rights, name+uid identity), blocking semantics (lean:
blocking round-trip, stop-flag rule applies)
- acceptance sketch: employee sample as A, a thin employee-report
client as B (read-only GroupBy over the wire) + audit-log writer
exercising the rights matrix
- slots after 9b (shares its typed surface), before 10 (HTTP is the
external face; this is the writeonce-native one); prior art:
04-client-api.md wire protocol + the WAL's value encoding
- roadmap + status board rows added
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
- `woc` now emits `.wob` that `wovm` runs: emit.ml lowers the typed,
owner-annotated AST (scope-stack registers with a >64 WO-E401 diagnostic,
Lua-style call windows, ICALL by slot, dedup const pool, drop maps, line
tables, implicit terminators); disasm.ml backs `--dump-bc` goldens.
- Ownership lowering consumes the four owner tables verbatim; RESIDUAL is the
only source of borrow ops, coalesced per operand. Review caught the emitter
consuming only 2 of owner.ml's 4 residual producers — an assignment-anchored
aliasing violation ran to exit 0 instead of trapping; fixed, plus a backstop
raising WO-E404 for any residual region left unconsumed.
- Conformance harness `scripts/oop-e2e.sh` (`just oop-e2e`): four fixture
kinds with exact outcomes — byte-exact stdout, one WO-E### anchored on
`error CODE:`, numeric trap code, gc trace. 25 fixtures incl. pricing-demo
logic, the ownership suite, and DB_STUB's parse-but-trap. `tests/` un-ignored
so the corpus is actually tracked.
- `woc build` produces a self-contained binary: wovm copy + appended image +
20-byte trailer, self-exec via /proc/self/exe. Verified relocated outside
the repo, argless, and against adversarial trailer corruption.
- Milestone 1's five spec criteria all MET (`just oop-accept`). Criterion 3
closed by WO-E405 — the entry must return `Int`, since program mode already
says its return value is the exit code — which deletes the leak class
without adding return-type metadata to the format. `gc/held-cycle` retired:
an externally-held cycle is not expressible in a post-exit pump.
- New spec: inferred GC + incremental per-shard tri-color mark-sweep, retiring
`@gc` and reference counting. Story gains iterations 7b (that work) and 9b
(`@table`, relations, compiler-checked query); `.dev/reference` gains a
sparse System.Linq checkout. Priority: 5→6→7 (log-watcher) then 7b, 8, 9, 9b.
- 00-kanban.md rebuilt: ▶ NEXT PLAN pointer (iteration 4 — emitter, corpus,
`woc build`) then six buckets — stories, in progress, done, pending,
discarded, learnings. It tracked only the Rust runtime before, so the whole
OOP track (wovm shipped, woc Tasks 1-8 shipped) was invisible.
- Board now records iteration 3's known gaps instead of silently owing them:
`?T` plumbed but unenforced; E205/E201/E203/E204 dead, so structural
interface satisfaction is unchecked.
- New discarded.md — settled rejections with reasons so they are not
re-proposed: inheritance, `abstract` newtypes, Money/SKU/Float, Dynamic/cast/
macro/extern, AOT-to-C, Menhir, shared engine state, external deployer.
- RECOVERED docs/plan/exploration/blue-green-vm/00-vision.md — gone from disk,
never committed (gitignored path), cited by five docs incl. principle 12.
- Root cause was broader: all seven forward-roadmap plans in
docs/superpowers/plans/ were untracked and ignored, on one disk only. Rules
were half-fiction — 33 of 34 exploration files were already tracked, so they
swallowed only *new* files.
- Dropped the docs ignore rules (exploration, oop-vm, superpowers/plans,
examples/agent-loop, examples/mcp-think) with a do-not-re-add comment; added
__pycache__/*.pyc. `tests/` stays ignored but warns that the next plan lands
the corpus there.
Completes plan 2 Tasks 7-8. owner.ml: mutable-value-semantics flow analysis
producing the four plan-3 emitter tables (moves, drops incl. LIVE-MASK for trap
unwinding, rc with elision, residual borrow sites) plus WO-E301-304 two-site
diagnostics. Alias questions run over canonicalized places, so a double-mut
reached through let-bound aliases lands in the residual table like the direct
form; dump.ml's contract notes the emitter must coalesce guards per operand.
main.ml: directory discovery, cross-file programs (symbols merge before bodies
check), diagnostics ordered by (file,line,col), new WO-E214 for a name declared
in two files. New docs/plan/oop-vm/01-error-catalog.md (14 emitted + 10 reserved
codes), un-ignored so both plan tracks can cite it; justfile regains woc-*.
builtin_scalars is now the five that work: Int, Bool, Text, Timestamp, Id.
Money/SKU/Float and the abstract_types allowlist are gone — `abstract` never
lexed, and Float had no literal syntax and no wob kind, so no value could exist.
Fixtures and samples retype Money->Int, SKU->Text. The abstract newtype feature
is rejected outright (verdict row adopt->reject); haxe-parity Task 7 keeps `is`.
nullable-types-implementation.md corrected: ?T is plumbed but UNENFORCED
(E211-213 declared, never emitted; probe exits 0), handed to haxe-parity Task 6
as next work item. Records all 10 dead codes incl. E205 — interface satisfaction
is unchecked. crates/rt keeps its Money/SKU fixtures (opaque strings, Stage 2).
Gate: build warning-clean, 14 + 264 checks 0 failures, pricing golden exit 0,
docs/examples histograms unchanged (13/70, zero WO-E225).