Skip to content

PRD: simplify Statum into Lite with Validators core #21

Description

@eboody

Problem Statement

As the maintainer of Statum, I need the implementation to become dramatically smaller and easier to reason about. The current codebase carries a wide guarantee surface: compile-time typestate, typed rehydration, source-backed lookup, introspection, presentation metadata, runtime recording, projection helpers, and rich diagnostics. That breadth has driven the implementation from a compact macro system into a much larger and more fragile one.

From the maintainer's perspective, the core problem is not file organization alone. The implementation currently promises more than is necessary for the main value of the library, which makes change harder, review slower, semantic drift more likely, and correctness boundaries harder to maintain.

The desired outcome is a much narrower Statum that keeps the most valuable parts of the product -- compile-time typestate and validator-based single-item rebuilds -- while deliberately removing or extracting broader lifecycle, runtime, and source-reconstruction features.

Solution

Statum should be narrowed into a Lite-with-Validators core.

From the user's perspective, Statum Lite with Validators should remain a compile-time typestate toolkit that:

  • defines legal states with #[state]
  • defines machines with #[machine]
  • defines explicit transitions with #[transition]
  • constructs fresh typed machines through generated builders
  • performs synchronous single-item typed rebuilds through #[validators]

Everything outside that narrow surface should be removed from the Lite core or explicitly moved out of scope. The implementation should stop trying to provide broad source-backed semantic reconstruction, authoritative introspection, runtime graph tooling, projection support, async validator flows, batch rebuild surfaces, and presentation/reporting layers.

The resulting product should be smaller, more bounded, easier to test, and easier to evolve honestly.

User Stories

  1. As the Statum maintainer, I want the library to have a much smaller guarantee surface, so that the implementation becomes easier to understand and change.
  2. As the Statum maintainer, I want the implementation to reflect only the guarantees we are willing to support long-term, so that the codebase stops carrying speculative or overly broad machinery.
  3. As the Statum maintainer, I want typestate construction to remain first-class, so that the main value proposition of Statum is preserved.
  4. As the Statum maintainer, I want explicit transitions to remain simple and central, so that users still get compile-time method-surface changes by state.
  5. As the Statum maintainer, I want validators to remain available, so that users can still rebuild a typed machine from one persisted value.
  6. As the Statum maintainer, I want validator support to be deliberately narrow, so that keeping validators does not force the rest of the system to remain complex.
  7. As a Statum user, I want to keep declaring states and machines with a small macro surface, so that adoption remains straightforward.
  8. As a Statum user, I want fresh machine construction through generated builders, so that creating legal typed machines remains ergonomic.
  9. As a Statum user, I want direct transitions and transition-with-data helpers, so that normal in-memory workflow code keeps working.
  10. As a Statum user, I want validator-based rebuilds for a single persisted item, so that I can still move one stored row or value into a typed machine.
  11. As a Statum user, I want validator methods to stay synchronous and simple, so that the rebuild model is easy to understand.
  12. As a Statum user, I want validator methods to take only &self, so that the API stays mechanically simple and predictable.
  13. As a Statum user, I want validator machine lookup rules to be explicit and narrow, so that unsupported forms fail clearly instead of being guessed.
  14. As a Statum user, I want same-module machine references to keep working, so that ordinary local usage stays convenient.
  15. As a Statum user, I want anchored machine paths like crate::, self::, and super:: to work, so that cross-module validators remain possible without broad inference.
  16. As a Statum user, I want unsupported alias-based machine references to fail closed, so that rebuild semantics remain predictable.
  17. As a Statum user, I want imported or re-exported machine names to be unsupported in Lite, so that the macro does not need a large source-chasing engine.
  18. As a Statum user, I want batch rebuilds to be out of scope for Lite, so that the implementation does not carry collection-oriented builder complexity.
  19. As a Statum user, I want async validators to be out of scope for Lite, so that rebuild semantics remain synchronous and local.
  20. As a Statum user, I want rebuild reports to be out of scope for Lite, so that the validator feature remains about typed acceptance rather than diagnostic trace modeling.
  21. As a Statum user, I want introspection to be out of scope for Lite, so that the core library stays focused on compile-time state safety rather than graph authority.
  22. As a Statum user, I want presentation metadata to be out of scope for Lite, so that the core library does not carry rendering-oriented structure.
  23. As a Statum user, I want runtime transition recording to be out of scope for Lite, so that the library remains compile-time-first.
  24. As a Statum user, I want projection helpers to be out of scope for Lite, so that storage/event-shaping concerns live elsewhere.
  25. As a Statum user, I want strict-versus-relaxed introspection mode complexity removed from Lite, so that the core story is easier to understand.
  26. As a Statum user, I want unsupported generated-source fallback behaviors to be removed, so that feature boundaries are explicit.
  27. As a Statum maintainer, I want diagnostics to stay precise but simpler, so that error quality remains useful without requiring heavy source reconstruction.
  28. As a Statum maintainer, I want source observation authority to be minimized, so that the macro no longer needs to approximate broad program structure.
  29. As a Statum maintainer, I want unsupported syntax and resolution forms to be rejected early, so that Lite stays honest and small.
  30. As a Statum maintainer, I want the README and docs to describe the narrowed product accurately, so that public claims match the implementation.
  31. As a Statum maintainer, I want examples to reflect the narrowed scope, so that users learn the right mental model from the start.
  32. As a Statum maintainer, I want tests to focus on the kept core guarantees, so that deleted features stop dominating maintenance cost.
  33. As a Statum maintainer, I want a clear migration story for users of removed features, so that scope reduction is explicit rather than surprising.
  34. As a user relying only on compile-time typestate and simple validators, I want my supported use cases to continue working, so that Lite remains practical.
  35. As a user relying on removed rebuild or introspection features, I want documentation to clearly tell me those workflows are no longer part of Lite, so that I can decide whether to stay on full Statum, refactor, or adopt a future companion package.
  36. As the maintainer, I want the remaining core to center on a few deep modules with stable interfaces, so that most internal churn can happen behind simple boundaries.
  37. As the maintainer, I want the validator path-resolution boundary to be mechanically narrow, so that its implementation stays testable and easy to reason about.
  38. As the maintainer, I want transition semantics to center on direct machine targets and explicit data transitions, so that the transition engine no longer carries broad wrapper and graph interpretation complexity.
  39. As the maintainer, I want removed features to be clearly marked as removed or extracted, so that there is no hidden compatibility theater.
  40. As the maintainer, I want Lite to be small enough that future contributors can understand the implementation without reconstructing several subsystems at once, so that maintenance cost drops materially.

Implementation Decisions

  • The Lite core will keep only the compile-time typestate surface plus narrow synchronous validator-based single-item rebuilds.
  • The core retained user-facing interfaces are: state declaration, machine declaration, explicit transitions, generated builders, transition-without-data, transition-with-data, and validator-based rebuild of one persisted value.
  • Validator machine lookup will be syntactic and narrow rather than broad and inferential.
  • Accepted validator target references will be restricted to same-module machine names and explicit anchored machine paths rooted at crate::, self::, or super::.
  • Lite will not resolve validator targets through imported names, renamed imports, re-exports, type aliases, or other source-chasing indirection.
  • Lite will fail closed on unsupported path forms instead of attempting broader recovery.
  • Validator execution will remain synchronous and local.
  • Validator methods will continue to operate on the persisted input through &self rather than an expanded general-purpose runtime protocol.
  • Rebuild will remain single-item only within Lite. Batch-oriented rebuild surfaces are removed from the core contract.
  • Async validator support is removed from the Lite core.
  • Report-producing validator flows are removed from the Lite core.
  • Rebuild diagnostics may remain actionable, but they will no longer justify broad source reconstruction or runtime reporting structures.
  • Transition semantics in Lite will be centered on direct, explicit transition forms. Any wrapper semantics that exist only to support introspection or richer authority claims should be removed or separately re-justified.
  • Introspection is not part of the Lite core. This includes graph generation, transition-site authority claims, strict-versus-relaxed introspection policy, and downstream graph-oriented runtime APIs.
  • Presentation metadata is not part of the Lite core.
  • Runtime transition recording is not part of the Lite core.
  • Projection helpers are not part of the Lite core.
  • The implementation should prefer deep modules that own stable concepts with simple interfaces:
    • a state-declaration core
    • a machine-declaration core
    • a transition core for explicit direct edges
    • a validator core for narrow single-item rebuilds
    • a minimal source lookup boundary used only where Lite still genuinely needs source-backed information
  • The source lookup boundary should be reduced to the smallest honest surface needed for Lite validator and machine resolution, with no broad source-graph claim.
  • Documentation and crate positioning must be rewritten before or alongside code deletion so that the public contract shrinks before implementation details are removed.
  • Any removed features that may later deserve a future package or higher-tier API should be treated as out of Lite, not as soft-promised future compatibility.

Testing Decisions

  • A good test should assert external behavior and guaranteed failure boundaries, not internal file layout or helper structure.
  • Tests should focus on what Lite promises: successful state/machine/transition construction for supported forms, successful synchronous single-item validator rebuilds for supported path forms, and fail-closed rejection for unsupported forms.
  • Tests should explicitly cover the narrow retained validator lookup surface:
    • same-module machine targets
    • anchored crate::, self::, and super:: targets
    • rejection of imported, re-exported, aliased, or otherwise indirect targets
  • Tests should explicitly cover that batch rebuild, async validators, report flows, and removed introspection-oriented features are not part of Lite.
  • Tests should continue to use existing macro-focused prior art in the codebase, especially the current UI-style compile tests and focused unit tests around macro semantics.
  • The most important regression tests should sit around the deep modules that remain:
    • state parsing/validation behavior
    • machine parsing/emission behavior
    • transition acceptance/rejection behavior
    • validator path-resolution and rebuild behavior
  • Tests for removed features should either be deleted or moved out of the Lite core so the suite reflects the actual product boundary.

Out of Scope

  • Authoritative or exact machine introspection
  • Strict-versus-relaxed introspection policy
  • Presentation metadata and generated presentation overlays
  • Runtime transition recording and graph join surfaces
  • Projection helpers and event-log-oriented rebuild pipelines
  • Batch rebuild APIs and collection-oriented machine reconstruction
  • Async validators
  • Rebuild reports and structured rejection reporting surfaces
  • Broad source-backed alias chasing or semantic lookup through imports and re-exports
  • Generated-source fallback discovery through include! or similar mechanisms
  • Full machine-lifecycle management across persistence, replay, reporting, and runtime observation

Further Notes

  • This effort is a claim-narrowing exercise, not just a refactor. The simplification is only honest if the implementation and the public description shrink together.
  • Keeping validators means Lite is still broader than a construction-only typestate library, but it can remain meaningfully smaller than current Statum if validator scope is kept narrow and local.
  • The biggest simplification wins are expected to come from deleting implementation that exists only to uphold broad authority claims, broad source-observation behavior, runtime graph surfaces, or collection/async/reporting rebuild flows.
  • Migration guidance will be important. Users who rely only on direct typestate plus simple synchronous validator rebuilds should remain well served. Users relying on removed features will need explicit guidance about staying on full Statum, refactoring, or waiting for extracted companion packages if they are ever created.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions