- main.c, startup only: WO_DATA unset and a class carrying WO_CLASSF_TABLE
without WO_CLASSF_VOLATILE (`durable: true`, the default) refuses — exit 2,
one stderr line naming the class and the three ways forward (WO_DATA=<dir
or file>, WO_EPHEMERAL=1, @table(durable: false)); before, every write
was silently dropped at exit — the one outcome `durable: true` forbids
- WO_EPHEMERAL=1 (exact value) is the whole-program escape: one boot notice,
rc 0, the RAM path byte-for-byte the old one (db.c untouched); any other
value refuses; set alongside WO_DATA refuses regardless of tables; the
`resident: keys` loop still wins and is not rescued
- .wob v8: WO_CLASSF_TABLE 0x08 (WO_CLASSF_ALL 0x0f), set from emit.ml's
cr_is_table — the first cut keyed on !VOLATILE and refused every
class-bearing program (fibers' Tick, subprocess's ConnMsg), because v7
spelled `durable: true` as the mere absence of a bit
- loader refuses VOLATILE/RESIDENT_KEYS without the table bit ("storage
flags on a class that is not a @table"); a v7 image is refused by the
exact-match version check, as v7 refused v6; disasm prints `table`;
runner.ml's independent validator carries both rules; obj.h comment
- test_loader: test_storage_flags_need_table (forged flags word: both
refusals, and the same bits WITH the table bit load); no golden moved
- contract: docs/plan/oop-vm/00-wob-format.md "v8: the table bit"
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
(cherry picked from commit 863692a590d426da0047831ae315142ef5b24416)
- 16 tasks complete: arena, object model, borrow word, containers,
RC + budgeted cycle collector, wob_build, validating loader,
interpreter core (dual dispatch), object opcodes, drop-map unwinding,
builtins + DB_STUB + TRAP, ICALL, wovm CLI + just recipes
- 13 test suites × 2 dispatch flavors (ASan+UBSan) + CLI smoke, all green
- .wob v1 format pinned in src/wob.h + docs/plan/oop-vm/00-wob-format.md
- wo-rt.c reference event-loop preserved for sub-project 2
This is Iteration 2 of the OOP milestone; compiler front (Iteration 3)
is in progress on this branch. They meet at Iteration 4 (emitter+e2e).