LOX · EMBEDDED SEQUENCING

LOX Sequence

A reboot should return a process to a deliberate decision point.

A heap-free C99 sequencer advances through caller-defined steps and stores a portable, CRC-protected checkpoint. Recovery produces a verdict; application code chooses how to start from it.

DevelopmentC99MITCaller-owned state
Last verified
2026-09-18 · README, public header, recovery/storage docs and tests reviewed
Storage boundary
Application supplies persistence callbacks and durable writes
01 / RECIPE SHAPE

A sequence is an ordered step table with explicit policy

Each caller-defined step has a tag, action callback, timeout and resume policy. A sequence instance tracks its current step and invokes the action as the application advances it. Optional branching selects a next step through the library API; the application still owns the actions and external effects.

DEFINITIONStep tabletag · action · timeout · policy
→
RUNTIMECurrent stepcaller supplies now_ms
→
TRANSITIONUpdate progresscheckpoint through adapter
→
CALLERPerform effectshardware/process semantics

There is one active sequence per instance. `loxseq_step_age_ms()` measures time from the current boot-local step start; it does not reconstruct elapsed wall-clock time after reset.

02 / PORTABLE PERSISTENCE

Persist defined bytes, never a compiler’s struct image

The storage contract uses a portable 32-byte checkpoint record. The backend receives bytes through `write_checkpoint`, `read_checkpoint` and `erase_checkpoint` callbacks. The record is CRC-protected and includes format/version and sequence progress fields with compile-time layout checks.

The caller owns the medium and its durability properties. The library does not select flash pages, wear-level, guarantee atomic programming, or flush a device. A RAM-backed callback is suitable for unit testing but cannot establish persistence across power loss.

CHECKPOINT LIFECYCLE
step transition
↓
encode portable record
↓
storage callback writes bytes
↓
reboot: read → validate CRC/version
physical durability follows the backend contract
03 / BOOT DECISION

Recovery classifies state; the caller selects the start path

On boot, `loxseq_recover()` examines the stored record and returns a verdict. A cold start, resumable checkpoint, restart policy, safe initialization and operator wait are distinct outcomes. Corrupt or unsupported records and read failures take conservative fallback paths rather than being treated as valid progress.

read bytes→validate record→apply step policy→verdict→caller starts fresh / resumes / restarts / waits

Per-step policy can resume at the current step, restart that step from its beginning, or prohibit automatic resume. The API also exposes safe-init and operator-resolution paths. These are control-flow choices: they do not prove that repeating an external action is safe.

Recovery is not transaction rollback. If a step controls a pump, writes a remote service or moves physical equipment, the application must make that action idempotent or define a safe recovery procedure.
04 / TIME, BRANCHES AND TERMINAL STATE

Progress is explicit and time is supplied by the host

The caller passes `now_ms` into the sequencer. Timeout and step-age behavior therefore depends on the caller’s clock discipline and the library’s documented 32-bit wrap handling. No thread, timer interrupt, wall clock or heap is created internally.

Steps can complete, fail, pause, resume or abort, and optional branch targets can alter the next transition. Terminal completion erases the checkpoint; an erase error is reported as a storage error. Completed, aborted and failed terminal checkpoints are treated as tombstones rather than resumed work.

C99 · RECOVERY CHOOSES A POLICY PATH
loxseq_t seq;
loxseq_init(&seq, steps, STEP_COUNT, &storage);
loxseq_recovery_verdict_t v = loxseq_recover(&seq, reboot_reason);
switch (v) {
case LOXSEQ_RECOVERY_RESUME:    loxseq_start_resume(&seq, now_ms); break;
case LOXSEQ_RECOVERY_RESTART:   loxseq_start_restart(&seq, now_ms); break;
case LOXSEQ_RECOVERY_SAFE_INIT: loxseq_start_safe_init(&seq, now_ms); break;
case LOXSEQ_RECOVERY_OPERATOR:  loxseq_start_operator_wait(&seq); break;
default:                        loxseq_start_fresh(&seq, now_ms); break;
}
05 / VALIDATION SCOPE

Host tests exercise policy and failure paths

The README lists tests for a CRC known vector, invalid initialization, corrupt and unsupported checkpoint fallbacks, resume versus restart timestamps, reboot-counter saturation, branching, preconditions, timeout, pause/resume, abort, terminal erase failure, transition write failure, tag queries and time wraparound. It also describes Ubuntu, Windows and macOS build/test coverage, Ubuntu ASan/UBSan, installed C/C++ consumer builds and release metadata gates.

These are repository-declared CI checks and unit-test coverage, not evidence here of a particular current workflow run or of a hardware power-cut campaign. The storage contract and evidence matrix should be reviewed for a target integration.

06 / INTEGRATION LIMITS

The library checkpoints workflow position, not the world

  • Backend write, erase atomicity, endurance and power-loss behavior are the integrator’s responsibility.
  • A checkpoint cannot undo or deduplicate external side effects performed before reset.
  • Step callbacks and their hardware/process contracts belong to the application.
  • Elapsed step time is boot-local and is not restored as wall-clock time.
  • CRC detects accidental record corruption; it is not authentication or tamper protection.
  • The documented API is a sequencer, not a general workflow graph, recipe manager or safety certification.

LOX product family · All products