Skip to content

stablekernel/crucible

Crucible

License: Apache 2.0

Forge event-driven services in Go.

Crucible is a multi-module Go toolkit for building event-driven services. Its design philosophy is thin seams, no-op defaults, no forced dependencies: every cross-cutting concern (logging, tracing, metrics, IDs, time) is a small, consumer-providable interface with a do-nothing default. You bring your logger, your tracer, your clock — Crucible never makes you adopt its choices, and never leaks a third-party type into a public signature.

The state engine is the extreme end of this: stdlib-only, with no injected IO at all. The IO modules carry the heavier seams via injection, but follow the same rule — defaults are no-ops, nothing third-party is forced on the consumer.

Modules

Each module is independently versioned (per-module SemVer) and carries its own stability label.

Module What it is Status
state Full-featured, domain-agnostic statechart engine. Stdlib-only, no IO. experimental
state/analysis Static model-checking and path enumeration over a machine's IR. experimental
state/evolution Diffs two machine definitions and classifies the SemVer bump. experimental
state/conformance Reusable harness for driving golden scenarios against a machine. experimental
state/expr Rich expression tier: CEL-backed guards type-checked against the context schema. experimental
telemetry Vendor-neutral tracing/metrics interface for the IO modules. Stdlib-only. experimental
telemetry/slog log/slog adapter for the telemetry interface. experimental
telemetry/otel OpenTelemetry adapter for the telemetry interface. experimental
telemetry/datadog Datadog adapter for the telemetry interface. experimental
broker Message broker seam — publish/subscribe transport with injected adapters. planned
store Durable state/event store seam with graceful lifecycle. planned
sink Effect dispatch / egress seam for emitted effects. planned

The engine emits effects as pure data; the IO modules are the thin seams that carry those effects to real transports, stores, and sinks — each "bring your own adapter," none forced on the consumer.

Status

Early and evolving. The state module is now a complete, embeddable statechart engine — hierarchical, parallel, and final states; history; guard combinators; delayed transitions; invoked services; an actor model with message passing; snapshots; inspection; and JSON (de)serialization — backed by its analysis, evolution, and conformance companion packages. Treat its API as experimental until it reaches v1. The telemetry interface and its slog, otel, and datadog adapters are released. The broker, store, and sink modules are planned.

Roadmap — event-driven seams

The kernel emits effects as pure data; a small family of bring-your-own-adapter IO seams moves events to and from the outside world, each defaulting to a no-op and forcing nothing third-party on the consumer:

  • broker (planned) — pub/sub transport: publish emitted events and subscribe machines to external streams.
  • sink (planned) — egress fan-out: dispatch emitted effects to many outlets (SQL, Dynamo, StatsD, …), fire-and-forget.
  • source (exploring) — ingress: subscribe external streams and drive machines; the symmetric counterpart to sink.
  • bellows (exploring) — resilience seam: circuit-breaking and backpressure around the IO edges.

Durable state and event persistence is tracked separately with the durable runtime, not here.

Design & discussions

Design rationale and roadmaps live on the GitHub Discussions board, organized into the State Machine and Conventions categories. Start with:

Contributing

Contributions are welcome. See CONTRIBUTING.md for dev setup, the Mage targets, conventional commits, and the DCO sign-off requirement. By participating you agree to the Code of Conduct.

License

Licensed under the Apache License, Version 2.0. See NOTICE for attribution.

About

Forge event-driven services in Go

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Contributors

Languages