v0.6.0
-
Exports the tidy build helper through Marionette's dependency
build.zig.
The helper locates its own dependency, sosrc/main_tidy.zigresolves inside
Marionette while scan paths continue to resolve inside the consuming
package; a nested consumer build now guards that boundary. -
Clarifies the two supported network-testing altitudes. Node-scoped
std.Io.netis the canonical literal same-code path for codecs, framing,
partial I/O, and stream lifecycle; experimentalEndpoint(Message)remains
a protocol-modeling surface with an explicitly documented shallow-copy and
delivery contract. The redundant publicByteEndpointfacade is removed
while its pooled byte machinery remains private to deterministic
std.Io.net. -
Closes the simulator-TCB audit's runner and lifecycle gaps:
runSimCase
forwards every simulation option, keeps setup OOM distinct from scenario
failure, accepts infallible scenarios, deinitializes pointer-valued apps
before replay comparison, and rejects empty fuzz campaigns. Process-scoped
Env/Iocapabilities now fail while killed, manual restart invalidates
file caches, and a failed restart rolls back partial tasks and handles. -
Hardens suspension and trace ownership. File metadata has stable allocation
across disk-latency suspension, guarded fiber-stack arithmetic is checked,
network enqueue/dequeue publishes only after fallible trace recording, closed
streams reclaim queued pooled frames, async/group storage honors dynamic
alignment, killedGroup.awaitowners release their group state before the
fiber stack is destroyed, and trace-summary plus low-level world time/random
state roll back cleanly on allocation failure. Suspended file operations now
hold kill-safe path snapshots, streaming operations reacquire handles on
resume, and per-path leases serialize pathname mutations with in-flight I/O.
Queued handle operations therefore follow a completed rename or reject a
completed deletion instead of recreating or writing through an obsolete
pathname. Process kill retires task-owned gate state and aborts a
main-context pathname wait instead of letting a stale capability keep
driving the scheduler. Killed async tasks now release their copied closure
contexts and never-started scheduler adapters immediately; only the future
result record remains until its requiredawait/cancelcollection. -
Makes final stream delivery transactional: the I/O bridge borrows a ready
frame, reserves inbox capacity, publishes the network andio.nettrace pair
atomically, and only then removes the frame. Allocation failure leaves the
original bytes queued for an exact retry. -
Confines every
RealDiskoperation beneath its configured root by walking
parent components through non-following directory handles and refusing final
symlinks. Exclusive create plus non-following reopen closes the create race;
the regression covers every file surface and verifies outside data is
unchanged. -
Makes
Env.io()the single application-facing authority for clocks, sleeps,
and randomness, removing the parallelEnv.clock/Env.randominterfaces
and routing BUGGIFY draws throughstd.Random.IoSource. Scheduler timer
jumps cross automatic process/network fault boundaries and yield to work
created at each intermediate boundary, whileWorld.clock()remains the
explicit raw harness clock. App sleeps round to ticks, stale killed-node I/O
returnserror.Canceled, full-range task-start jitter and network-latency
jitter avoid overflow, beyond-clock process and network transitions stay
inert, and failed liveness transitions remain retryable. Tidy now targets
Zig 0.16's real escape hatches—alternate host I/O backends, raw OS access,
global logging, host-only process queries, threads, and ambient allocators—
instead of obsolete time, entropy, filesystem, and network APIs. -
Makes the disk contract match its declared sector model: torn writes land a
prefix of whole sectors, reorder is one consistently traced crash-global
reversal, and scripted corruption rejects missing files. The WAL example now
spans two sectors so its planted recovery bug depends on a real sector-prefix
tear instead of accidental byte tearing. Reclassifies XITDB-001 as a
Marionette model bug: its minimized 7-byte-sector counterexample disappears
under the corrected whole-sector prefix model while the same crash-point
sweep continues to exercise real unacknowledged windows. -
Canceling a task blocked in
Group.awaitnow cancels the group's members,
waits for their completion, and resurfaceserror.Canceledto the outer
future. -
Updates the dusty crash and shutdown validations for upstream commit
e7a4f4b: a dead pooled connection is evicted so the same client redials
after server restart, and graceful shutdown with a parked keep-alive handler
completes instead of timing out. The old DUSTY-001/002 scenarios remain as
positive regression coverage for the upstream fixes. The fixed revision is
now pinned inbuild.zig.zon. -
Removes the cancelled production endpoint bus, its deprecated
Production.endpoint/byteEndpointmethods, and the private FIFO/socket
transport. Production networking is hoststd.Io.net; Marionette endpoints
are simulation-only. This also removes the blocking host-accepttest from
the ReleaseSafe gate. -
Binding a simulated
std.Io.netlistener to port 0 now allocates an
ephemeral port, matching POSIX bind semantics (issue #2). Ports come
from the IANA dynamic range (49152-65535) via a rotating cursor shared
across process backends, so ports are unique world-wide, allocation is
deterministic per seed, and a just-closed port is not immediately
reused. The assigned port is surfaced through the returned socket's
address (server.socket.address.getPort()), andlistenfails with
AddressInUseonly once the whole range is occupied. -
Completes the architecture clobber set in Marionette's corrected fiber
context switch. The x86_64 LLVM path now names thexmmandymm
aliases as well aszmm, so CPUs without the wider register classes do
not retain stale SIMD values across a switch. AArch64 now clobbers the
allocatablex18on targets such as Linux while omitting it on Android,
Darwin, Fuchsia, Windows, and OpenHarmony targets where LLVM reserves it
as a platform register by default. -
Hardens stream write backpressure from review findings. Writers now
park on a world-global backpressure key instead of their own
connection, so a writer blocked because another connection filled the
shared byte pool is woken by any drain, not only its own peer's; a full
directed path queue (EventQueueFull) now backpressures the same way
instead of failing the write withSystemResources; and the peer is
re-resolved and validated before every retry, so a peer that closes or
dies while the writer is parked surfaces asConnectionResetByPeer
rather than a stale-pointer retry. -
Adds opt-in randomized task start jitter
(simulate(.{ .task_start_jitter_ns = ... })): every scheduler-backed
task draws a seeded initial delay and becomes runnable only after that
much virtual time, so seed sweeps explore start orderings the
cooperative scheduler otherwise masks structurally. A capability test
deterministically reproduces a connect-before-listen race and replays
it byte-identically from its seed. The option defaults off, consumes no
randomness, and emits no trace when disabled, so existing traces are
unchanged; enabled draws are trace-visible asscheduler.start_jitter. -
Lands 16e, large transfers: a dusty scenario uploads a 512 KiB
position-patterned body the server verifies byte-for-byte, then
downloads a 1 MiB chunked body the client verifies byte-for-byte, both
over one keep-alive connection and spanning hundreds of simulated
packets. This forced two stream-fidelity fixes in the simulated
std.Io.netbackend: writes larger than a pool slot are now segmented
into 16 KiB frames like a real transport instead of failing with
MessageTooLarge, and a full byte pool now applies write backpressure
(the writer parks until the receiver drains a frame and wakes it)
instead of surfacingNetworkDownmid-stream. Two peers both blocked
writing at each other is a real deadlock, exactly as on TCP, and
surfaces through deadlock detection. -
Lands 16d, dusty pooled keep-alive depth: a pool-reuse scenario (idle
gaps in virtual time, concurrent fetches growing the pool, sequential
fetches reusing both connections, connection count pinned via the new
io.net.connecttrace event) and a pool-poisoning crash scenario
(serverkillProcessunder a pooled keep-alive connection, restart
through a registered lifecycle, fresh-client isolation probe). Pins
netShutdownunder partition in the before-response scenario: shutdown
is local in simulation, succeeds mid-partition, and is trace-visible as
the newio.net.shutdownevent; partition-respecting peer visibility is
a recorded gap. -
Records two confirmed dusty 0.1.0 bugs found by the 16d scenarios
(FOUND_BUGS DUSTY-001/002): the client connection pool never evicts a
dead connection because write failures never mark it closing, so a
poisoned client can never recover even after the server returns; and the
server's graceful-shutdown drain busy-spins forever once any earlier
connection has closed, because the drain waits on a latched, never-reset
std.Io.Event. -
Adds
mar.expectTraceContains, the trace-substring assertion the dusty
and xitdb validations each defined privately; failures print the needle
and the trace tail. -
Removes the World-config runner family:
runCase,expectPass,
expectFailure, andexpectFuzz. It was a complete parallel API to
runSimCase/expectSim*with no consumers; harnesses with genuinely
custom state driveWorlddirectly or use the world-onlymar.run.
Checkandworld_checksstay, since the sim runner accepts them. -
Removes the
SimControlroot export;Controlis the single name for
the simulator-control capability bundle (the two were aliases of the
same type). -
Removes
ByteTransport,CodecTransport, and thecodecnamespace
(includingCodecRecvLifetimeanddefault_codec_encode_buffer_size).
These were convenience wrappers with a single in-repo consumer, and a codec
interface is a serialization concern that belongs to the app, not the
simulator. The toy SQL example now encodes into an owned, value-only
Endpoint(Message)payload; the redundant public byte-endpoint facade is
removed as described above. -
Adds the pinned lazy beanstalkz validation (
validate-beanstalkz): the
unmodifiedg41797/beanstalkzwork-queue client runs against a
harness-owned in-memory beanstalkd speaking the text protocol over
simulatedstd.Io.netstreams. Covers a produce/consume round trip with
bury/kick transitions and the pinnederror.Timeoutempty-reserve
contract, sequential connection churn (connect, put, quit,
shutdown(.both), close) drained in FIFO order, a blocking
reserve-with-timeoutparked across a five-second virtual publish
delay, and a server-process crash under a parked reserve that surfaces
the pinnederror.CommunicationFailurereset contract before a
registered restart recovers on a fresh incarnation. All scenarios replay
byte-identically from the same seed.