- Plan docs: architecture, woc front (Tasks 2-7), emit+e2e (Plan 3), Haxe parity (Plan 8) - nullable-types implementation plan - Iteration 3: compiler front story - Specs: systems track, blue-green VM, log-watcher sample, OOP compiler/VM - Principles + project structure - Kanban updated with compiler front-end progress
10 KiB
log-watcher .wo sample (docs-first) + principles doc — design spec
Date: 2026-08-07
Status: approved design, pre-implementation
Scope: authoring two docs artifacts — the docs/examples/log-watcher/ sample and docs/00-principles.md
Companion specs: 2026-08-01-systems-track-design.md (language surface + stdlib + sample mapping), 2026-08-01-oop-compiler-vm-design.md (OOP core, memory model), 2026-08-03-blue-green-vm-design.md (in-runtime deployment)
Companion plan: docs/superpowers/plans/2026-08-01-log-watcher-sample.md (plan 10 — the executable acceptance plan this authoring feeds)
Motivation
The systems track names ~/projects/log-watcher (~1,200 lines of Haxe, a
single-binary Linux daemon) as its driving workload and defines the sample
port in Part 4 of its spec. Plan 10 sequences that port but gates on plans 8
(language adoptions) and 9 (stdlib) shipping, because its acceptance requires
compiling fixtures. This session does not wait: it authors the sample as a
docs-first artifact — the same pattern by which docs/examples/blog/ and
docs/examples/ecommerce/ existed before the runtime executed them and
thereby forced the grammar. Alongside it, the repo gains its first canonical
principles document, docs/00-principles.md, distilling doctrine currently
scattered across specs, plan docs, and CLAUDE.md.
Decisions locked during brainstorming
| Question | Decision |
|---|---|
| Session deliverable | Sample .wo files + principles doc now, docs-first. No compiler/runtime code; fixtures stay with plan 10. Rejected: waiting for plans 8/9; revising approved specs; starting compiler implementation. |
| principles doc placement | Repo-level: docs/00-principles.md. The example README links to it. Rejected: per-example principle file. |
| Sample scope | Approach A + short deploy note: all 8 files per plan 10's structure, strict approved syntax, README mapping table, plus one README paragraph linking the blue-green spec. Rejected: minimal 3-file sample (breaks the mapping, leaves could-not-express unproven); full speculative wo remote walkthrough. |
Section 1 — Scope & positioning
In scope: docs/examples/log-watcher/ — eight .wo files plus an
orientation README — and docs/00-principles.md.
Out of scope: corpus fixtures, just recipes, compiler or runtime code,
kanban restructuring. Plan 10 keeps ownership of fixtures and of acceptance
criteria 4–5 (empty could-not-express column verified by a real compile; live
silent-death detection) when plans 8/9 ship.
Authoring contract: every construct used in the sample must be traceable
to an approved surface — the OOP spec's section 3 (classes, interfaces,
methods, MVS parameter conventions), the systems-track verdict table's adopt
rows (switch expressions, typedef records, ?T optionals, enum payloads,
try/catch/throw, static fn, using, use modules, pub, abstracts,
interpolation, #if), Part 2 program mode (fn main, blocking builtins,
env.stopping()), and Part 3's five stdlib modules (fs, proc, net,
time, json). No construct may be invented here. If the port cannot
express a behavior inside that surface, that is a defect report against
plans 8/9, recorded in the README's could-not-express column — the same
feedback-loop role plan 10 assigns, run early.
Behavioral reference: the Haxe source at ~/projects/log-watcher/src/.
The port is behavior-faithful, not line-faithful; each .hx file is read
before its .wo sibling is written. Deliberate divergences (optionals over
sentinels, records, switch expressions, RAII handles, the stopping-flag
daemon idiom) are recorded in the README table, never silent.
Section 2 — The sample
File set and content, matching plan 10's structure:
.wo file |
.hx sibling |
carries |
|---|---|---|
logtail.wo |
LogTail.hx | TailState record; bounded fs.read_at tail polls (never front-to-back); rotation restart on inode change or shrink; burst jump to tail; torn-final-line holdback; line classification by level prefix incl. timestamped app-log lines |
watcher.wo |
Watcher.hx | the alert rule: last entry error + quiet period elapsed → alert transition; injected clock parameters |
cron.wo |
Cron.hx | cron.d entry parse (five-field schedules, user column); >> logfile redirection extraction (the zero-config watch derivation); same-log collapse; next-fire computation; unreadable directory reported as skipped data, never a throw |
probes.wo |
Flock.hx, Pgrep.hx | static fn probes over proc.run: flock exit-1-means-held with exists-guard, pgrep exit-0-means-alive, unknown codes falling in the safe direction |
supervisor.wo |
Supervisor.hx | single-threaded tick loop; rescan interval; pre-fire lock probes (PROBE_LEAD); watch activation/completion; error-only JSONL detections through fs.append; daemon shape while !env.stopping() { tick; time.sleep } |
mcp.wo |
Mcp.hx | typed request/response records; pure handle(req) -> resp, socket-free (the original's best design decision, preserved); Bearer auth first; method/path/size gates; JSON-RPC envelope (initialize, ping, tools/list, tools/call; notifications answered 202); serve loop over net.listen/accept on 127.0.0.1, one request per connection |
tools.wo |
Tools.hx | tool subset over shipped capability: list_logs, tail_log, search_log as bounded windows over fs.read_at; the sqlite-backed minilog tools are scoped out to the DB track (recorded as scoped-out, not could-not-express) |
main.wo |
Main.hx | fn main(args: multi Text) -> Int; subcommands watch / run / mcp; config decoded via json.decode … as into a record with ?fields; usage text and exit codes on bad invocation |
README.md (orientation only, per repo docs rule):
- the mapping table above with two more columns: divergences (each
deliberate
.wo-idiom improvement) and could-not-express (defects against plans 8/9; target empty); - a status line: authored ahead of the compiler; plan 10 verifies by compilation and fixtures when plans 8/9 ship;
- one paragraph linking the blue-green spec: this daemon is the shape of
program the runtime updates in place — propose, approve, atomic switch,
resident rollback — via
wo remote, once that subsystem ships; - a pointer to
docs/00-principles.md.
Section 3 — docs/00-principles.md
One page; each principle is a short statement, a one-line why, and a link to the spec or doc that enforces it. The thirteen principles (the thirteenth added 2026-08-08 by story amendment):
- One binary is the whole system. App, database, API, and UI ship as a single deployable; there is nothing else to operate.
- Zero dependencies — kernel primitives only. libc-only C runtime, stdlib-only OCaml compiler; epoll/io_uring, inotify, signalfd are the framework.
- Memory safety without a GC tax. Mutable value semantics: single
owner, second-class borrows (the Rust-borrow shape without lifetime
inference), hybrid static+runtime enforcement;
@gcis a per-class opt-in collected per shard with no global pause. - No inheritance, ever. Composition, structural interfaces, and tagged
unions; no
extends, nooverride, no virtual hierarchies. - Thread-per-core shards; ownership moves, data never shares. Cross- shard communication is a message send; no shared mutable engine state.
- The runtime never stops. Blue/Green VM slots, in-runtime compile, atomic dispatch switch, resident rollback; the binary embeds its own source.
- RAM is authoritative; the WAL makes it durable. Ack after fsync; mirrors (Postgres) are reconstructible backups, never a commit path.
- Samples force the grammar. Examples are the de facto integration tests; a feature exists when a sample exercises it.
- Linux is the target. The kernel is the substrate, not an abstraction boundary to hide.
- Capabilities are typed builtins. No FFI, no shell strings, no escape hatches; the read-only posture is the default posture.
- Plain diagnostics are the product. Stable error codes, two-site ownership messages; MVS only beats Rust ergonomics if the errors are plain.
- The runtime is a recipe box. Web frameworks and databases arrive
later as
.wolibraries composing separable runtime capabilities, not as monoliths. - Statically typed, all the way to the register. No
Dynamic, nountyped, nocast; untagged VM registers because the compiler knows every slot's type;@-annotations are the compile-time ORM.
Placement note: docs/ currently starts at 01-problem.md; 00- is free
and reads as "start here". CLAUDE.md's "Where to read next" gains one line
pointing at it (smallest possible touch).
Section 4 — Error handling (in the authored artifacts)
The sample demonstrates the approved error doctrine rather than inventing
one: optionals (?T) for expected absence (missing stat, failed decode,
missing env var), try/catch over traps for genuine faults, throw only
where the original throws. The probes' Haxe catch (e:Dynamic) return false
idiom becomes optional-returning calls — a README-tabled divergence.
Section 5 — Verification (docs artifact, this session)
- Surface audit: every construct in every
.wofile traceable to a verdict-table row, OOP spec section 3, or Part 2/3 of the systems spec; anything else is removed or logged as could-not-express. - Behavior audit: every
.wofunction names its.hxsource behavior; the mapping table is complete (eight rows, no blank cells). - Principles audit: every principle's link resolves to an existing doc; no principle contradicts a locked decision.
- Spec self-review per the brainstorming skill, then user review.
- Compilation, fixtures, and the live silent-death scenario remain plan 10 acceptance — explicitly not claimed here.
Success criteria
docs/examples/log-watcher/holds the eight.wofiles and README; the mapping table's could-not-express column is empty or contains only defect reports filed against plans 8/9.- Every construct used is traceable to approved specs (surface audit passes).
docs/00-principles.mdexists with the thirteen principles, each linked to its enforcing doc; CLAUDE.md points at it.- The example README links the blue-green spec and the principles doc.
- Nothing outside
docs/and CLAUDE.md is touched; no fixtures, no code.