Commit graph

62 commits

Author SHA1 Message Date
64a4700190 docs: reconcile story 34 + gates with merged master
- 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>
2026-08-22 23:30:55 +02:00
ee018f06e2 Merge branch 'read-path-index' 2026-08-22 23:26:01 +02:00
dc3e5b7e5b Merge branch 'db-bench' (iteration 22 — durability/throughput baseline)
- 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>
2026-08-22 22:57:51 +02:00
4ec01c4c43 Merge branch 'concurrency-arc-stage3' (iteration 8 complete)
- brings arc stage 3: transparent DB actor (T7) + closeout (T8),
  db-actor sample + gate, board/story reorg (stories/00-status.md)
- conflicts resolved: runtime CODE-LOGIC (kept iteration 36 bitwise
  section AND stage-3 DB-actor section), board in-progress table
  (kept iteration 36 + framework rows AND db-bench row, links fixed
  for the moved board path)
- full battery fresh-built 11/11: woc-build wovm-build woc-test
  wovm-test oop-e2e deps-accept web-app log-watcher employee fibers
  db-actor (first run hit a stale pre-merge wovm — gates require
  built binaries and never rebuild; builds now run first)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 22:50:18 +02:00
ed6bfeea3d feat: iteration 36 task 5 — operators sample, docs closeout
- docs/examples/operators: manual-test workload (ok/FAIL lines per
  expression; trap mode proves WO_T_SHIFT); NO test fixtures by
  developer directive — acceptance is the manual pass
- 00-wob-format.md: v6 section (opcodes 42-46, T_SHIFT, header v6)
- CODE-LOGIC.md both sides: precedence-into-existing-rungs, Lua not,
  rewind-and-reparse compound assigns, trap-not-mask, 63-bit hex limit
- story 36 refine -> in-progress with landing blockquote; board updated
- gates: woc-test 543/0, wovm-test ASan, oop-accept ALL MET,
  deps-accept 8/0, web-app 26/0

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 21:42:08 +02:00
6f7fc577c3 docs: story 36 + plan — operator parity (not, bitwise, hex literals, compound assigns)
- story: gap survey vs Go reference; forks settled (arithmetic >>, trap
  on out-of-range shift count, Lua-placement not)
- plan: 5 tasks, lexer -> parser -> checker -> emit/VM (.wob v6) -> closeout
- latent defect recorded: += / -= lex but never parse (dead tokens)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-22 21:18:33 +02:00
526a837102 docs: story 35 — net runtime seams (deadlines, unix sockets, peer addr)
- 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>
2026-08-22 17:37:12 +02:00
38457973c3 docs: story 34 — crypto builtins (digests + HMAC)
- 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>
2026-08-22 17:34:27 +02:00
b3baf6dd9a docs: story 33 — single-file store (WO_DATA=<path>.db)
- 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>
2026-08-22 17:32:18 +02:00
5d6a72bb82 docs: iteration 22 landed — closeout (T6)
- story 22 to done/ with landing banner (numbers, deviations,
  standing multi<TableClass> finding); marker deleted
- board standup from measured numbers; next slice = 31 (has its
  mutex-inbox number now); spec/plan banners LANDED; graph node done
- msgrate floors value/8 (quick's small N spawn-dominated, grazed /4)
- full battery + db-bench-quick 87/0 green; links verified

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 16:57:27 +02:00
3a30b4ac3b feat(db-bench): first baseline — the measurement contract (T5)
- 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>
2026-08-21 16:54:13 +02:00
555a836d90 docs: iteration 22 plan ready; slice active
- plan 2026-08-21-db-bench.md: 6 tasks (time.ticks builtin, sample,
  concurrent modes, driver+gate, first baseline + gate-bites proof,
  closeout); words + verification commands per convention
- spec banner APPROVED; story 22 to in-progress/ (frontmatter synced);
  marker doc created; board standup/rows/pending updated

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 16:07:51 +02:00
49cc734ae8 docs: arc closeout (T8) — stage 3 landed, chain advances to 22
- stories 08+11 to done/ with banners (11: fs-park re-scoped out of
  v1, disclosed); guarantee-contract table re-homed in story 08;
  marker doc deleted per convention
- board standup: implemented/findings/learned/unblocked/next/.dev-ref
  for the landing; In-progress = nothing active, next = 22 spec
- arc plan status ARC COMPLETE, T7/T8 boxes checked with deviations;
  graph nodes done; framework ledger rows note arc-unblocked;
  18's pub/sub rejection expired note
- CODE-LOGIC: runtime DB-actor + ring-params section, database slot
  surface; oop-vm/03 contract gains the reply-park protocol
- 22 precursor recorded: remote insert ~8us/op RAM-only
- full battery + db-actor gate green after doc edits; links verified

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 13:16:25 +02:00
ca2ed96e49 docs: story frontmatter + Dataview board views
- 28 story files gain YAML frontmatter: iteration id, status
  (mirrors folder), chain position (7 files, positions 1-6)
- board-views.md: Dataview queries (not-done, by-status lanes,
  chain order, active); Kanban caveat — view only, frontmatter
  is source of truth, folder move + status key change together
- board points at the views

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 12:17:50 +02:00
e7ca2fdd7c docs: stage 3 refined with guarantee contract; story 32 born
- 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>
2026-08-21 11:26:45 +02:00
eacc7fe4f2 docs: oop-vm/03 — stackless coroutine contract (no async)
- normative reference for the concurrency chain: fiber = interpreter
  state, suspension only at VM boundaries, park/resume protocols
  (re-execute vs continue-past, park_wr_at), back-edge budget,
  no-coloring rule, rejected-alternatives table
- README slot 03 repointed (old shard-actor row rode discarded plan 4)
- story 11 links the contract

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 11:07:52 +02:00
299b448181 docs: active stories 08+11 into stories in-progress/ (slip fix)
- 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>
2026-08-21 06:21:33 +02:00
f691818c4b docs: in-progress/ marker — arc stage 3 is the active slice
- 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>
2026-08-21 06:19:03 +02:00
d3f77d6850 docs: discard 2026-08-01 shard-actor plan (epoll-based)
- 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>
2026-08-21 05:59:21 +02:00
1cfcd6292a docs: stories 08+11 promoted to root — ready to implement
- 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>
2026-08-21 05:10:39 +02:00
039cb9ba4f docs: concurrency chain re-refined + resequenced
- order now stage 3 -> 22 -> 31 -> 24 -> 23: correctness before
  measurement (multi-shard DB traps WO_T_DB today)
- stories 08/11 catch up to landed arc stages 1+2 (plan of record,
  deviations, settled open questions)
- 22 gains multi-shard + mutex-inbox targets; deltas owed retroactively
- 23 rides arc's per-shard ring (T4); old-id order string superseded
- 24 depends on 31; 19 landed so Bytes ready
- new story: refine/31-actor-lifecycle.md (request/response,
  bounded mailboxes, death/supervision, timers)
- 00-story table + 00-status pending resequenced; held rows link
  hold/; ids stay immutable, no renames

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-21 05:01:11 +02:00
b4d9d507a0 docs: sync superpowers specs/plans to hold decision
- 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>
2026-08-21 05:00:56 +02:00
26bfc42bfe hold few iterations 2026-08-21 04:11:10 +02:00
d24c705860 feat: iterations 19 + 17 — Float/Bytes scalars (.wob v5), library kind + internal/
- 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>
2026-08-20 19:24:15 +02:00
5521d21a84 docs: pending iterations renumbered by dependency + priority
- 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>
2026-08-20 14:31:09 +02:00
4c8a3bd2ed docs: iteration 20 — Float + Bytes, the missing scalars (forks settled)
- 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>
2026-08-20 14:21:58 +02:00
2a4c304378 docs: stories foldered by state — done/ and refine/
- 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>
2026-08-20 04:33:24 +02:00
ba428c362c docs: story iterations table re-sequenced by dependency
- 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>
2026-08-20 04:25:43 +02:00
234bd43466 docs: framework v1/v2 split + per-feature status ledger
- 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>
2026-08-20 04:07:39 +02:00
deb2dc805c docs: iteration 18 — memory-rich features over the embedded DB (no code)
- brainstorm settled four forks same-day: scope = TTL cache + @table
  feature flags + durable @table job queue; jobs = drain-on-request
  (idle server drains nothing, disclosed); transaction { } ships in 18
  (WAL already stages batches, db.c merely commits per statement);
  pub/sub REJECTED until 8/11 (no WebSockets, starvation lesson)
- ground truths verified and recorded: time.now exists, no timers (lazy
  expiry only), accept blocks without timeout, state lives on wired
  instances, wal_append*/wal_commit is the txn seam
- headline: enqueue + business write in ONE commit — outbox dissolved
- draft acceptance incl. SIGKILL/restart transactional-jobs proof
- board row 18 + NEXT PLAN next-step + story roadmap row

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 03:52:59 +02:00
0dd5fda180 feat(framework): multipart/form-data parsing — Part, multipart_parts, part_named
- http/multipart.wo: RFC 7578 whole-body parsing within BODY_MAX —
  boundary from the raw content-type (quoted or bare, key
  case-insensitive), parts split on --boundary, each part = headers,
  blank line, content; filename + per-part content-type kept (lowercased)
- strict malformed-is-nil: no closing --boundary-- marker, a part
  without content-disposition, missing blank line, no boundary param,
  wrong media type — all nil, the caller's 400
- part_named(parts, name): first matching field's content, caller-owned
- web-app CreateProduct now accepts multipart/form/JSON (curl -F shape)
  into the shared insert path
- probe 13/13 + 3x reuse loop (fields, crlf-in-content, quoted boundary,
  file part, zero-part close, five malformed shapes) release + ASan
- gate grows 19 -> 21: multipart create 201, missing closing marker 400
- README: multipart row ✅ (all three body hooks done), limits updated;
  story 16 + board record the landing
- gates: web-app 21/0, oop-e2e 89/0, deps-accept 8/0, log-watcher 7/0,
  employee 8/0, woc-test green

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 03:33:14 +02:00
a5826495e9 feat(framework): form-encoded body parsing — media_type + form_values
- media_type(req): content-type lowercased, "; charset=..." stripped,
  "" when absent — the content-negotiation hook
- form_values(req): application/x-www-form-urlencoded body -> decoded
  pairs through the existing query decoder ('+' as space, %XX); nil on
  any other content-type so a JSON body is never misread as a form key
- web-app CreateProduct accepts form OR JSON; shared create_product
  insert path; field/number validation answers 400
- probe 7/7 (plus/pct decode, empty value, case + charset param, json
  and missing content-type nil, empty body, media_type strip) + ASan
- gate grows 17 -> 19: form create 201 with decoded name, non-numeric
  price 400; hit() gains a content-type argument
- README: checklist row form ✅ (multipart stays candidate), limits
  paragraph updated; story 16 + board record the landing
- gates: web-app 19/0, oop-e2e 89/0, deps-accept 8/0, log-watcher 7/0,
  employee 8/0, woc-test green

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 03:21:48 +02:00
fb86156d04 feat(framework): auth in core — Bearer/Basic mechanism + principal slot
- http/auth.wo: auth_header (scheme split, case-insensitive, RFC 9110),
  bearer_token, basic_credentials (first-colon split, RFC 7617),
  pure-.wo base64_decode (RFC 4648, strict padding), ct_eq constant-time
  compare (no early exit, both Basic fields always compared)
- req.principal: the blessed "who is this" slot, "" until authenticated;
  Middleware.before now takes mut req so auth can write it
- BearerAuth { token, principal } and BasicAuth { user, pass, realm }
  middlewares; BasicAuth answers the WWW-Authenticate challenge; policy
  (routes/users/secrets) stays app-side on the exposed fns
- web-app dogfoods BearerAuth; its hand-rolled Auth class deleted
- probe matrix 26/26 (RFC 4648 vectors, rfc7617 pair, pass-with-colon,
  bad padding/chars/length, deny paths, challenge header) release+ASan
- gate grows 16 -> 17: wrong bearer token answers 401 over the wire
- README: auth bullet + the core CHECKLIST (done / candidate / parked
  behind 8-11 by design); story 16 + board record the landing
- all gates green: web-app 17/0, oop-e2e 89/0, deps-accept 8/0,
  log-watcher 7/0, employee 8/0, woc-test green

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-20 03:15:16 +02:00
d84b72f0b4 feat(framework): v1 polish — helpers, 405+Allow, HEAD, Logging, set_header
- 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>
2026-08-20 03:04:57 +02:00
2b5762500b docs: goal shift — log-watcher (met) to web framework as library
- 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>
2026-08-20 02:04:41 +02:00
d1aab85dbe docs: sequence pending iterations in implementation order
- 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>
2026-08-20 01:50:03 +02:00
3e22e42da5 docs: iteration 17 forks settled — kind key, internal/ rule (no code)
- 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>
2026-08-20 01:45:06 +02:00
f430bff5c4 docs: iteration 17 — library projects + dependency privacy (needs refinement)
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>
2026-08-20 01:23:10 +02:00
d6025e131d docs: iteration 16 closeout (Task 6)
Board row 16 -> landed (web-app 14/0), pending row removed; story header
records the landing + the two as-built discoveries (idle-keep-alive
starvation policy; the two compiler gaps the chain exposed and fixed);
README gains the framework+web-app sample entry; plan checkboxes ticked.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:58:13 +02:00
4c75ba4fbd docs: implementation plan for iteration 16 (web framework + web-app)
6 tasks, words-only: (1) framework skeleton — Req/Resp records + builders,
standalone-typechecking project; (2) HTTP/1.1 parse/serialize + keep-alive
serve loop with the try-bounded dispatch seam (400-close on malformed, 500-
survive on handler traps, fd/stop clean); (3) router with :param captures +
Handler/Middleware interfaces + App.serve; (4) web-app storefront —
@table Product/Order, auth middleware, json routes, [deps] manifest carrying
the future GitHub URL; (5) scripts/web-app-accept.sh — temp git remote from
the framework dir, file:// substitution into a temp app copy, full curl
matrix + restart persistence + SIGTERM + opt-in soak, wired as just web-app;
(6) docs closeout. Both enabling risks retired pre-plan (interface-field
dispatch probe; owned-move container fix pinned by run/container-owned-move).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:38:21 +02:00
f6b5333d40 docs: iteration 15 closeout (Task 5)
- error catalog: WO-E106 (dependency fetch/shape failures, one code, message
  names dep + step) and WO-E107 (dep/local module-name collision) rows.
- README: a Dependencies subsection under the manifest docs — [deps] syntax,
  .wo-deps/wo.lock behavior, offline-when-locked, --update-deps, flat-only.
- board: iteration 15 row -> landed (deps-accept 8/0), pending row removed;
  story 15 header records the landing; 08-project-structure notes
  .wo-deps (gitignored) + wo.lock (committed); plan checkboxes all ticked.

(One self-inflicted casualty during this task, restored from git before
commit: a buggy doc-edit script truncated 08-project-structure.md; the file
was recovered intact and the intended one-liner applied by hand.)

Gates at closeout: deps-accept 8/0, woc-test 540/0, oop-e2e 87/0,
log-watcher 7/0, employee 8/0.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:23:18 +02:00
8fcebe60f9 docs: implementation plan for iteration 15 (deps)
5 tasks, words-only per house rule, each with its verify step: (1) manifest
grows the [deps] section + one-line inline-table value (only under [deps]);
(2) resolver — git-binary fetch into .wo-deps/, wo.lock pinning, warm-path
offline guarantee, drift diagnostic, --update-deps, guard rails (transitive
refusal, non-writeonce dep, name collision WO-E107, all fetch failures
WO-E106); (3) multi-root discovery + module_of prefixing dep roots by dep
name + entry restricted to the app's own files; (4) scripts/deps-accept.sh
gate over file:// remotes (8 checks, network-free) + just recipe; (5) docs
closeout (catalog E106/E107, README deps subsection, board/story/structure).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 19:11:05 +02:00
976ccda225 docs: web framework + deps design — spec + iterations 15/16
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>
2026-08-19 19:07:16 +02:00
28485a271c docs: iteration 7b migration — amend the normative docs (Phase 4)
The spec's §8 migration table, applied:

- 00-principles.md P3: "@gc is a per-class opt-in, reference-counted" ->
  GC-ness is inferred; incremental per-shard mark-sweep in budgeted slices;
  still no global pause by construction.
- OOP spec: decision-table GC row -> inferred (hybrid rule named); §3 rule 5
  -> traced classes alias freely, which classes is inferred; §4 memory model
  -> the RC + Bacon-Rajan paragraph replaced by tracing (snapshot roots,
  Yuasa barrier, born-black, budgeted slices); header rc comment -> union'd
  sweep link; mixing rule restated for tracing.
- 00-wob-format.md: header says version 4; opcodes 27-28 -> reserved (loader
  rejects); the owned-temporary rule's @gc exclusion restated for tracing.
- 08-builtin-surface.md: the push RC_INC special case and the set(m,k,v)
  retention gap DELETED — neither exists without RC; the corpus cycle is
  collected by tracing.
- story 07b: status -> LANDED 2026-08-18 (with the historical note kept);
  board: 7b row ✅ (supersedes iteration 2's RC memory model), pending row
  removed.
- gc-cycle README: Phase 3 flipped to landed (the ring runs, is reclaimed,
  ASan-clean; the ?Node RC_DEC-on-nil trap no longer exists); the barrier
  prose corrected to the as-built design (snapshot-at-beginning + deletion
  barrier + born-black, not per-slice root re-reads).
- plan 2026-08-18: all checkboxes ticked + a completion banner recording the
  four deviations from the plan as written.

(Error catalog was already amended with the keyword-removal commit: WO-E104
added, WO-W201 retired.)

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-19 17:11:35 +02:00
b6151333c3 docs: iteration 14 — skillhost as a host-shaped driving workload
- 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>
2026-08-16 19:53:06 +02:00
86e1fd4a4e docs: iteration 9g story -- query grammar from real embedded-DB corpora
- 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>
2026-08-16 19:28:25 +02:00
edd6091579 Merge branch 'query-surface' into database-engine 2026-08-16 19:01:16 +02:00
2677c1457e feat: FK restrict on delete + employee sample runs; group-by parked (9b)
- FK restrict: deleting a row a non-nullable `ref` still points at traps
  WO_T_FK (11), catchable. The compiler now records a `ref` field's
  target class in the class-table field_class metadata; the engine
  (wo_row_has_referrers) scans referencing scalar columns before a
  delete. Correctness-first full scan; the backlink-index optimization
  is recorded for later
- docs/examples/employee now COMPILES AND RUNS all six modes against a
  WAL-durable database: seed (+@unique trap across restart), report
  (per-dept aggregates + payroll), staff (unique probe + backlink +
  ref nav), raise (update-through-row), drop (FK restrict), and
  persistence via replay
- group-by SYNTAX parked to a future iteration (user decision): the
  report mode is hand-rolled from the shipped primitives meanwhile
  (same numbers). "table relations and FK" is complete
- scripts/employee-accept.sh (8 checks) + a `just employee` module;
  manifest parser tolerates iteration 9c's [share]/[[share.clients]]
  sections so `woc .` builds the sample on this branch
- fixtures trap/db-fk-restrict (code 11) + run/db-fk-restrict-catch;
  oop-e2e 79/0, woc-test 566/0, 15 runtime suites, log-watcher 7/0,
  employee-accept 8/0
- 9b story + status board updated

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-16 18:37:23 +02:00
ad8cfb456e docs: iteration 13 story -- compile-time metaprogramming (derive)
- 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>
2026-08-16 04:57:00 +02:00
71d3985e81 docs: performance arc as story iterations (9e measure, 9f io_uring)
- 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>
2026-08-15 22:12:48 +02:00