Skip to content

v0.5.0

Choose a tag to compare

@sb2bg sb2bg released this 06 Jul 08:15
· 143 commits to main since this release
  • Adds the one-shot liveness transition sim.transitionToLiveness(core),
    following the VOPR transition_to_liveness_mode shape: zeroes every
    probabilistic simulator fault rate (process dynamics, network lossiness,
    clog and partition dynamics, disk faults, allocation faults), restores
    links, clogs, and node-down state inside the core, restarts a crashed
    disk, and revives killed core processes through their registered
    lifecycles, while non-core failures stay permanent. Trace-visible as
    liveness.transition and network.liveness_restore; a second call
    asserts as harness misuse, and recoverable validation errors (invalid
    core node, killed core process without a registered lifecycle) are
    checked before any state changes so a failed call stays retryable.
  • Keeps consumer builds lean: Marionette's build script registers only the
    public modules when built as a dependency, so depending on Marionette no
    longer fetches its lazy validation SUTs (xitdb, mailbox, Ochi, dusty, and
    their transitive dependency trees) or runs their build scripts, one of
    which shelled out to git and printed fatal: not a git repository noise
    into consumer projects.
  • Documents the user-facing API surface with contract-level doc comments
    (errors, trace events, alignment and determinism rules): Env
    authorities, the network/disk/process/allocation simulator controls and
    their option structs, SimProfile, SimCase accessors, endpoints, the
    disk handle, and the message pool, so editor hover shows the same
    contracts as the API doc.
  • Adds simulated netLookup for address literals: IPv4/IPv6 literals and
    RFC 6761 localhost names resolve deterministically through the std
    queue protocol (trace event io.net.lookup), so an unmodified
    std.http.Client request against a simulated server succeeds, including
    the localhost two-candidate connectMany race where the v6 loopback
    attempt fails cleanly and v4 wins. Real DNS, /etc/hosts, and search
    domains remain explicitly unsupported (error.UnknownHostName), and the
    fetch replays byte-identically from the same seed.
  • Settles two simulator-wide conventions and documents them in the
    determinism doc: a disabled fault (zero rate) consumes no randomness and
    emits no trace, so Env.buggify at .never() no longer draws or records;
    and misaligned runFor durations assert as harness misuse across
    SimControl and network control instead of returning
    error.InvalidDuration. The buggify change can shift seed streams for
    workloads that rolled zero-rate hooks, which is why it lands inside the
    0.5 release boundary.
  • Adds the structural disk crash trigger control.disk.crashAfterOps(n):
    the disk crashes at the operation boundary after n more data/metadata
    operations, trace-visible as disk.fault kind=armed_crash. The xitdb
    crash-fault fuzzer now arms the trigger instead of measuring an
    undisturbed victim run and sleeping to a tick offset: measureVictimTicks
    is gone, each fuzz case runs once instead of twice, and the shrink test's
    crash-point scan is self-bounding via the passed_no_window outcome.
  • Adds guarded fiber stack-overflow diagnostics on POSIX guard-page targets:
    task fibers register their guard regions with task/process metadata, and a
    SIGSEGV/SIGBUS handler on the alternate signal stack writes a targeted
    stderr diagnostic (task id, owning process, configured stack size, the
    task_stack_size fix) when a fault lands in a registered guard, then
    chains to the previously installed handler so Zig's Debug trace still
    shows the fault site. Non-guard faults chain through unchanged. Subprocess
    tests cover both the overflow diagnostic and the non-fiber fall-through;
    embedders opt out with simulate(.{ .fiber_overflow_diagnostics = false }).
  • Adds the deterministic allocation authority core: Env.allocator() returns
    an app-facing std.mem.Allocator, simulation wraps the harness allocator
    with deterministic fail-after, live-byte quota, and BUGGIFY allocation
    faults configured through control.allocation, and allocation decisions
    are traced without raw addresses. Production envs return the caller-provided
    backing allocator with no faults.
  • Adds the memtable allocation-pressure example: allocation failure is a
    modeled branch with a clean-rejection oracle, a planted commit-before-
    allocate bug the checker catches under deterministic OOM, and a
    buggify_rate fuzz scenario.
  • Documents the allocation authority in the API and trace-format docs,
    including the decision that all allocation operations are traced by
    default.
  • Raises the default scheduler task stack from 256 KiB to 1 MiB. dusty's
    Debug-mode client fetch path needs more than 640 KiB, and fiber stacks are
    lazily paged mmap regions on guard-page targets, so the increase costs
    address space rather than resident memory.
  • Adds a pinned lazy dusty validation that runs the unmodified HTTP
    client/server library through simulated std.Io.net streams: routed GET
    and POST echo over one keep-alive connection, an exact response oracle,
    and byte-identical same-seed replay.
  • Re-scopes the 0.6 roadmap target from production Endpoint(Message)
    transport to SUT-driven deterministic std.Io.net depth, and defers the
    production transport chain to 0.7.
  • Adds cooperative cancellation following std.Io's protocol: Future.cancel
    and Group.cancel arm a one-shot request that delivers error.Canceled at
    the task's next cancellation point (checkCancel, futexWait, sleep,
    netAccept, netRead, netWrite), interrupting cancelable parks
    immediately. recancel re-arms, swapCancelProtection defers delivery,
    uncancelable waits defer to the next point, and group members are canceled
    in ascending task order. Requests and deliveries are trace-visible as
    scheduler.cancel_request / scheduler.cancel_deliver.
  • Runs the dusty validation through dusty's real Server.listen accept loop:
    multi-connection accept, keep-alive reuse, and two cancel-driven shutdown
    shapes, both with byte-identical same-seed replay. A clean shutdown
    delivers error.Canceled in the accept park with nothing left to drain;
    a hung-connection shutdown leaves a keep-alive handler parked in a read,
    so dusty's drain times out and its deferred group cancel sweeps the parked
    handler.
  • Adds dusty HTTP fault scenarios with an oracle: partition before response
    and mid-response through futex handshakes, pin dusty's observed
    error.Timeout contract under a severed link, heal and retry with a fresh
    client, require exact response bodies, reject short-success partial chunked
    responses, and sweep every chunk cut point across deterministic seeds.
  • Fixes closed-handle retirement when a canceled net wait loses a race with
    a concurrent close: the canceled accept/read paths now retire closed idle
    handles exactly like the woken paths.
  • Defines the recovery-window vocabulary (durability boundary, durable truth,
    recovery window, destructive budget) in the disk fault model, with the KV
    example as the worked case: crash fault classes apply only to pending
    writes, and damaging durable truth requires an explicitly destructive
    fault. Adds the probabilistic KV recovery search: a window checker that
    asserts synced records recover exactly while unsynced records may be
    absent or exact but never damaged, held across a 32-seed fuzz, plus a
    seed search that finds the planted magic-only recovery bug as
    DamagedRecordAccepted.
  • Adds the KV compatibility validation, a local storage surrogate that uses
    std.Io WAL appends, file sync, tmp-file compaction through rename,
    directory sync, WAL clear/delete, and crash-point fuzzing across aligned and
    misaligned sectors. Its oracle accepts either physical incarnation around
    pending metadata while requiring recovered key/value durable truth to
    converge exactly.
  • Expands the xitdb crash-fault profile into a fuzzer with shrinking. Each
    case runs a seed-planned transaction workload, commits a durable setup
    boundary, then crashes the disk at a seed-varied simulated time while the
    final transaction runs mid-commit as a cooperative task, applying exactly
    one crash fault class (lost, torn, or reordered) to pending writes across
    512/4096-byte sectors. Failures shrink greedily to a 1-minimal transaction
    and operation sequence rendered as a readable repro. The shrinker
    demonstrably reduces the characterized XITDB-001 sub-field torn-header
    boundary (7-byte sectors) to at most three transactions.
  • Fixes operation-scoped buffer leaks when a task is killed while parked in
    a disk-latency wait: sector scratch and resolved-path buffers held across
    std.Io file-operation suspension points now register with the backend
    and killed-task survivors are swept after task retirement, since a killed
    fiber never runs its defers.
  • Widens the fiber stack guard from one page to a 256 KiB PROT_NONE region,
    so Debug-mode stack frames larger than a page fault at the overflow
    instead of silently corrupting neighboring mappings. The widened guard
    immediately caught a latent overflow in the dusty hung-shutdown
    validation that the single-page guard had missed. Adds
    SimulateOptions.task_stack_size so a simulation can raise the
    scheduler task stack for deep SUT call chains; the dusty validation now
    uses 8 MiB.