Skip to content

feat: state machine self check - #137

Merged
Theauxm merged 2 commits into
mainfrom
feat/state-machine-self-check
Sep 1, 2026
Merged

feat: state machine self check#137
Theauxm merged 2 commits into
mainfrom
feat/state-machine-self-check

Conversation

@Theauxm

@Theauxm Theauxm commented Sep 1, 2026

Copy link
Copy Markdown
Member

No description provided.

…onformance helper

Two pieces every consumer of a machine-with-a-twin writes for itself, found by auditing the first one
(nwyc) that got far enough to need them.

StateMachineSelfCheckHealthCheck had zero product content: resolve every registered IMachine, call
SnapshotSelfCheck.Run, map an empty result to Healthy. It belongs next to the thing it checks, with
AddTraxStateMachineSelfCheck() so a host adds it in one line and a newly-registered machine is picked
up with no edit.

MachineConformance folds the three drift checks a generated twin needs into one call. Written by
hand they come out as three test files with two copies of the same path plumbing and no statement
anywhere of why three are needed, so the helper documents that: the IR check catches a machine edit
that skipped regeneration, the corpus check catches a build that shipped a stale golden, and the
self-check catches an engine that no longer reproduces it. It is framework-agnostic like
DifferentialCorpus -- returns problems, asserts nothing -- because consumers are split across NUnit
and xUnit.

The corpus check is new rather than lifted: consumers compare the committed corpus by replaying it,
which cannot tell them their assembly embedded a different one. Comparing the file to the embedded
copy closes that, and makes the self-check's result meaningful.

Still to move, both blocked on packaging rather than design: a default HttpContext-backed
ISnapshotPrincipal, and the Testcontainers + AddStateMachines + AddTraxGraphQL server fixture every
e2e rebuilds. Both need ASP.NET Core references that Persistence deliberately does not have, so they
want a .AspNetCore package rather than being forced in here.
…nformance

The health check is thin but its three claims are not: corpus-less machines are
skipped rather than failed, every divergent machine is named (not just the first),
and the registration resolves IEnumerable<IMachine> at run time, which is what lets
a host add the line once and have a machine discovered later be covered. The last
one only shows up through HealthCheckService, so the AddTraxStateMachineSelfCheck
tests build a provider and read the report rather than inspecting registrations.

MachineConformance gets both verdicts of each leg over real files: a missing
artifact, a stale one, a committed corpus that differs from the embedded copy, and
a machine whose engine no longer replays what it ships. The trailing-newline
tolerance is pinned too, since committed artifacts carry one and the in-memory
forms do not.

The fakes live in the Persistence test project because MachineConformance is over
IMachine, and the declarative Machine<,> turnstile is already there.
@codecov

codecov Bot commented Sep 1, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

@Theauxm
Theauxm merged commit 8c92054 into main Sep 1, 2026
3 checks passed
@Theauxm
Theauxm deleted the feat/state-machine-self-check branch September 1, 2026 19:36
@github-actions

github-actions Bot commented Sep 1, 2026

Copy link
Copy Markdown

This PR is included in version 1.52.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant