Expand description
shigoto (仕事) — the typed job-system primitive.
Umbrella crate. Re-exports the public surface of every sibling so
consumers depend on shigoto = "0.1" and reach the full algebra
via use shigoto::{Job, JobId, Scheduler, ...}; without naming
every sub-crate.
Canonical spec: theory/SHIGOTO.md.
Theory frame: theory/THEORY.md §IV (Motion).
Re-exports§
pub use shigoto_gate;
Structs§
- AllUpstreams
Terminal AllUpstreamsTerminal— every direct DAG predecessor has reached a terminal phase ({Succeeded, Skipped, Deadlettered}). The scheduler implicitly applies this gate to enforce DAG edge semantics; consumers don’t normally register it explicitly.- Budget
Spec - Budget
Tree - Three-dimension budget envelope. Allocation checks every applicable limit (min-intersection): a job runs iff all three have slack.
- Dag
- Typed DAG of JobIds. Edges declare “to may not start until from
reaches a terminal phase” (Succeeded | Skipped | Deadlettered).
Acyclic by construction at edge-add time would require an O(V+E)
check on every insert; instead, cycles are detected at
toposort()/waves(), where consumers must run before scheduling anyway. - Failure
Record - Gate
Context - Everything a Gate needs to make its decision: the job in question,
the FSM snapshot (every other job’s phase), the DAG (so gates
like
AllUpstreamsTerminalcan ask about predecessors). - Illegal
Transition - Rejected transition —
(from, signal)is not a legal FSM cell. Returning Result instead of panicking lets consumers report drift (an operator action attempting an illegal transition) without crashing the scheduler. - InMemory
Sink - In-memory
JobId → Outputmap. The consumer reads viadrain(clears + returns) orsnapshot(clones + keeps) after ticks complete.Arc<Mutex<...>>interior so the same sink can be shared between the Job (recording) and the consumer (reading). - InProcess
Scheduler - Default scheduler — single-process, in-memory FSM state, sequential execution within a wave.
- JobId
- Typed identity for a Job. Stable across cycles + scheduler restarts.
- JobKind
Id - Typed work-class identifier. Stored as
String(not&'static str) so it serializes through serde without lifetime constraints. CheapCloneis fine for the volume we expect (≤ ~100 kinds across the whole scheduler). - Null
Sink - No-op sink — discards every output. Default for Jobs that don’t need their typed Output surfaced.
- Operator
Approved OperatorApproved— pass iff an external operator has flipped a pre-arranged flag. The flag itself lives in the consumer’s state store; this gate is a thin wrapper that holds anArc<AtomicBool>or similar. v0.1 ships with aClosurevariant that takes aFn() -> boolfor tests + ad-hoc cases.- Snapshot
- Read-only snapshot of the scheduler’s current FSM map.
- Tick
Receipt - Derived per-tick rollup the scheduler emits on every
tick. - Transition
Event - Unhealed
Drift
Enums§
- Budget
Error - DagError
- Gate
Aggregate - Aggregate gate outcome — what the cohort of gates collectively said. Per §III.9 individual gates return Pass / Wait / Skip; the aggregate is the worst outcome (Skip > Wait > Pass) per a typed reducer in shigoto-gate. We carry the rolled-up result here so the FSM stays language-agnostic about how the rollup is computed.
- Gate
Outcome - JobPhase
- FSM phase a Job inhabits. See
theory/SHIGOTO.md§III.3 for the transition table. - JobScope
- JobSubject
- Retry
Decision - Retry
Outcome - Retry decision from a
RetryPolicy::decide()call. Same shape that shigoto-retry’sRetryDecisionexposes — duplicated as a typed signal payload so the FSM stays in shigoto-types without a dependency on shigoto-retry. - Retry
Policy - Scheduler
Error - Signal
- FSM driver — every legal way a Job’s phase can change. Exhaustive
over the
(JobPhase, Signal)cross-product pertheory/SHIGOTO.md§IV.1; theadvancetable below enumerates every cell. - Skip
Reason - Transition
Reason
Traits§
- Erased
Job - Trait-object dispatch surface. The scheduler holds
Box<dyn ErasedJob>(Jobitself isn’t object-safe because of the associated types);ErasedJobcollapses the typed Output + Error to()+ boxed error so the scheduler can store heterogeneous jobs in one DAG. - Gate
- One typed precondition. Pure — no IO. Gate impls that “need” IO are antipatterns; the right shape is a Job that emits a typed fact and a downstream gate that checks the fact.
- Job
- The typed Job trait — what every consumer’s domain-specific job
implements. Per
theory/SHIGOTO.md§III.1. - JobError
- JobInput
- Inputs / Outputs / Errors implement these marker traits so the scheduler can serialize across boundaries when persistence lands.
- JobOutput
- Output
Sink - Typed receiver for
Job::Outputvalues. Jobs callrecordon a successfulexecuteso consumers (reconcile receipts, audit trails, dashboards) can read the typed outcomes the scheduler’s phase-tracking discards. - Recording
Job - Convenience trait that captures the most common Job authoring
shape across pleme-io consumers: a Job whose typed Output flows
through an
OutputSinkfor consumer-side capture, and whose identity decomposes into (scope, kind, subject). - Retry
Decider - Scheduler
- Transition
Emitter - Receivers of
TransitionEvent. Thin trait over the canonicalshigoto_types::sink::Sink<TransitionEvent>so every consumer writingArc<dyn TransitionEmitter>keeps working unchanged after the theory/CONVERGENCE-ADOPTION.md Phase 0.1 extraction. The blanket impl below means anySink<TransitionEvent>impl auto-satisfiesTransitionEmitter— no per-impl wiring at the consumer side.
Functions§
- advance
- The canonical FSM driver. Pure: same
(from, signal)always produces the same result. Exhaustive overJobPhase × Signal— adding a new phase or signal fails to compile until every cell of the cross-product is decided.
Type Aliases§
- Audit
File Emitter - Append-only JSONL audit file. One event per line. Same shape as
tend’s existing
audit.rsso operators can grep both with the same tooling. Alias of the canonicalshigoto_types::sink::AuditFileSink<TransitionEvent>— JSONL serialization is byte-identical (oneserde_json::to_stringper line +writeln!append). - Multi
Emitter - Fan-out emitter — every inner sink receives every event. Alias of
the canonical
shigoto_types::sink::MultiSink<TransitionEvent>; inner sinks areArc<dyn Sink<TransitionEvent>>. - Null
Emitter - No-op emitter — the default for tests + consumers without
observability wired up. Sinks should compose via
MultiEmitterinstead of stubbing this in production. Alias of the canonicalshigoto_types::sink::NullSink<TransitionEvent>.