ready-active-safe 0.1.3

Lifecycle engine for externally driven systems
Documentation
# Machine

A pure function from `(mode, event)` to [`Decision`](decision.md).

`Machine` is the central trait of the lifecycle engine. Implementations define
how the system responds to events in each mode. The trait is deliberately minimal:
no `self` mutation, no time parameter, no I/O.

## Associated Types

- `Mode` — the set of lifecycle phases (e.g. Ready, Active, Safe)
- `Event` — external stimuli the system can receive
- `Command` — instructions for the runtime to execute

## Example

```rust
use ready_active_safe::prelude::*;

#[derive(Debug, Clone, PartialEq, Eq)]
enum Mode { Ready, Active, Safe }

#[derive(Debug)]
enum Event { Start, Stop, Fault }

#[derive(Debug, Clone, PartialEq, Eq)]
enum Command { Initialize, Shutdown }

struct System;

impl Machine for System {
    type Mode = Mode;
    type Event = Event;
    type Command = Command;

    fn initial_mode(&self) -> Mode { Mode::Ready }

    fn on_event(&self, mode: &Mode, event: &Event) -> Decision<Mode, Command> {
        match (mode, event) {
            (Mode::Ready, Event::Start) => transition(Mode::Active).emit(Command::Initialize),
            (Mode::Active, Event::Stop | Event::Fault) => transition(Mode::Safe).emit(Command::Shutdown),
            _ => ignore(),
        }
    }
}

let system = System;
assert_eq!(system.initial_mode(), Mode::Ready);
```

## `decide` — alias for `on_event`

```rust
# use ready_active_safe::prelude::*;
# #[derive(Debug, Clone, PartialEq, Eq)]
# enum Mode { Ready, Active, Safe }
# #[derive(Debug)]
# enum Event { Start, Stop, Fault }
# #[derive(Debug, Clone, PartialEq, Eq)]
# enum Command { Initialize, Shutdown }
# struct System;
# impl Machine for System {
#     type Mode = Mode;
#     type Event = Event;
#     type Command = Command;
#     fn initial_mode(&self) -> Mode { Mode::Ready }
#     fn on_event(&self, mode: &Mode, event: &Event) -> Decision<Mode, Command> {
#         match (mode, event) {
#             (Mode::Ready, Event::Start) => transition(Mode::Active).emit(Command::Initialize),
#             (Mode::Active, Event::Stop | Event::Fault) => transition(Mode::Safe).emit(Command::Shutdown),
#             _ => ignore(),
#         }
#     }
# }
let system = System;
let d = system.decide(&Mode::Ready, &Event::Start);
assert_eq!(d.target_mode(), Some(&Mode::Active));
```

## `step` — decide + apply in one call

```rust
# use ready_active_safe::prelude::*;
# #[derive(Debug, Clone, PartialEq, Eq)]
# enum Mode { Ready, Active, Safe }
# #[derive(Debug)]
# enum Event { Start, Stop, Fault }
# #[derive(Debug, Clone, PartialEq, Eq)]
# enum Command { Initialize, Shutdown }
# struct System;
# impl Machine for System {
#     type Mode = Mode;
#     type Event = Event;
#     type Command = Command;
#     fn initial_mode(&self) -> Mode { Mode::Ready }
#     fn on_event(&self, mode: &Mode, event: &Event) -> Decision<Mode, Command> {
#         match (mode, event) {
#             (Mode::Ready, Event::Start) => transition(Mode::Active).emit(Command::Initialize),
#             (Mode::Active, Event::Stop | Event::Fault) => transition(Mode::Safe).emit(Command::Shutdown),
#             _ => ignore(),
#         }
#     }
# }
let system = System;
let (mode, commands) = system.step(Mode::Ready, &Event::Start);
assert_eq!(mode, Mode::Active);
assert_eq!(commands, vec![Command::Initialize]);
```

## `step_checked` — decide + apply with policy

```rust
# use ready_active_safe::prelude::*;
# #[derive(Debug, Clone, PartialEq, Eq)]
# enum Mode { Ready, Active, Safe }
# #[derive(Debug)]
# enum Event { Start, Stop, Fault }
# #[derive(Debug, Clone, PartialEq, Eq)]
# enum Command { Initialize, Shutdown }
# struct System;
# impl Machine for System {
#     type Mode = Mode;
#     type Event = Event;
#     type Command = Command;
#     fn initial_mode(&self) -> Mode { Mode::Ready }
#     fn on_event(&self, mode: &Mode, event: &Event) -> Decision<Mode, Command> {
#         match (mode, event) {
#             (Mode::Ready, Event::Start) => transition(Mode::Active).emit(Command::Initialize),
#             (Mode::Active, Event::Stop | Event::Fault) => transition(Mode::Safe).emit(Command::Shutdown),
#             _ => ignore(),
#         }
#     }
# }
let system = System;

// Allowed
let (mode, cmds) = system.step_checked(Mode::Ready, &Event::Start, &AllowAll)?;
assert_eq!(mode, Mode::Active);

// Denied
let err = system.step_checked(Mode::Ready, &Event::Start, &DenyAll).unwrap_err();
assert!(matches!(err, LifecycleError::TransitionDenied { .. }));
# Ok::<(), LifecycleError<Mode>>(())
```

## See Also

- [`Decision`]decision.md — the return type of `on_event`
- [`Policy`]policy.md — transition guards used by `step_checked`
- [`Runner`]runner.md — owns mode and feeds events in a loop